diff options
124 files changed, 48888 insertions, 0 deletions
diff --git a/board/RPXlite/flash.c b/board/RPXlite/flash.c new file mode 100644 index 0000000..78c1838 --- /dev/null +++ b/board/RPXlite/flash.c @@ -0,0 +1,524 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Yoo. Jonghoon, IPone, yooth@ipone.co.kr + * U-Boot port on RPXlite board + * + * Some of flash control words are modified. (from 2x16bit device + * to 4x8bit device) + * RPXLite board I tested has only 4 AM29LV800BB devices. Other devices + * are not tested. + * + * (?) Does an RPXLite board which + * does not use AM29LV800 flash memory exist ? + * I don't know... + */ + +#include <common.h> +#include <mpc8xx.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); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ +/* volatile immap_t *immap = (immap_t *)CFG_IMMR; */ +/* volatile memctl8xx_t *memctl = &immap->im_memctl; */ + unsigned long size_b0 ; + int i; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ +/* + size_b0 = flash_get_size((vu_long *)FLASH_BASE_DEBUG, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } +*/ + /* Remap FLASH according to real size */ +/*%%% + memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000); + memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V; +%%%*/ + /* Re-do sizing to get full correct info */ + + size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]); + flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]); + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + /* monitor protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif + + flash_info[0].size = size_b0; + + return (size_b0); +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + /* set up sector start address table */ + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00010000; + info->start[2] = base + 0x00018000; + info->start[3] = base + 0x00020000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + ((i-3) * 0x00040000) ; + } + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + info->start[i--] = base + info->size - 0x00010000; + info->start[i--] = base + info->size - 0x00018000; + info->start[i--] = base + info->size - 0x00020000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00040000; + } + } + +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: printf ("AMD "); break; + case FLASH_MAN_FUJ: printf ("FUJITSU "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + 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; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + ulong value; + ulong base = (ulong)addr; + + /* Write auto select command: read Manufacturer ID */ + addr[0xAAA] = 0x00AA00AA ; + addr[0x555] = 0x00550055 ; + addr[0xAAA] = 0x00900090 ; + + value = addr[0] ; + + switch (value & 0x00FF00FF) { + case AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + + value = addr[2] ; /* device ID */ + + switch (value & 0x00FF00FF) { + case (AMD_ID_LV400T & 0x00FF00FF): + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (AMD_ID_LV400B & 0x00FF00FF): + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (AMD_ID_LV800T & 0x00FF00FF): + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (AMD_ID_LV800B & 0x00FF00FF): + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00400000; /*%%% Size doubled by yooth */ + break; /* => 4 MB */ + + case (AMD_ID_LV160T & 0x00FF00FF): + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (AMD_ID_LV160B & 0x00FF00FF): + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ +#if 0 /* enable when device IDs are available */ + case AMD_ID_LV320T: + info->flash_id += FLASH_AM320T; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ + + case AMD_ID_LV320B: + info->flash_id += FLASH_AM320B; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ +#endif + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + /*%%% sector start address modified */ + /* set up sector start address table */ + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00010000; + info->start[2] = base + 0x00018000; + info->start[3] = base + 0x00020000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + ((i-3) * 0x00040000) ; + } + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + info->start[i--] = base + info->size - 0x00010000; + info->start[i--] = base + info->size - 0x00018000; + info->start[i--] = base + info->size - 0x00020000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00040000; + } + } + + /* 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 */ + addr = (volatile unsigned long *)(info->start[i]); + info->protect[i] = addr[4] & 1 ; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr = (volatile unsigned long *)info->start[0]; + + *addr = 0xF0F0F0F0; /* reset bank */ + } + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + vu_long *addr = (vu_long*)(info->start[0]); + int flag, prot, sect, l_sect; + ulong start, now, last; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if ((info->flash_id == FLASH_UNKNOWN) || + (info->flash_id > FLASH_AMD_COMP)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[0xAAA] = 0xAAAAAAAA; + addr[0x555] = 0x55555555; + addr[0xAAA] = 0x80808080; + addr[0xAAA] = 0xAAAAAAAA; + addr[0x555] = 0x55555555; + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (vu_long *)(info->start[sect]) ; + addr[0] = 0x30303030 ; + l_sect = sect; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (vu_long *)(info->start[l_sect]); + while ((addr[0] & 0x80808080) != 0x80808080) { + 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; + } + } + +DONE: + /* reset to read mode */ + addr = (vu_long *)info->start[0]; + addr[0] = 0xF0F0F0F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long *)(info->start[0]); + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*((vu_long *)dest) & data) != data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[0xAAA] = 0xAAAAAAAA; + addr[0x555] = 0x55555555; + addr[0xAAA] = 0xA0A0A0A0; + + *((vu_long *)dest) = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/cogent/lcd.c b/board/cogent/lcd.c new file mode 100644 index 0000000..941ea65 --- /dev/null +++ b/board/cogent/lcd.c @@ -0,0 +1,231 @@ +/* most of this is taken from the file */ +/* hal/powerpc/cogent/current/src/hal_diag.c in the */ +/* Cygnus eCos source. Here is the copyright notice: */ +/* */ +/*============================================================================= */ +/* */ +/* hal_diag.c */ +/* */ +/* HAL diagnostic output code */ +/* */ +/*============================================================================= */ +/*####COPYRIGHTBEGIN#### */ +/* */ +/* ------------------------------------------- */ +/* The contents of this file are subject to the Cygnus eCos Public License */ +/* Version 1.0 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://sourceware.cygnus.com/ecos */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the */ +/* License for the specific language governing rights and limitations under */ +/* the License. */ +/* */ +/* The Original Code is eCos - Embedded Cygnus Operating System, released */ +/* September 30, 1998. */ +/* */ +/* The Initial Developer of the Original Code is Cygnus. Portions created */ +/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. */ +/* ------------------------------------------- */ +/* */ +/*####COPYRIGHTEND#### */ +/*============================================================================= */ +/*#####DESCRIPTIONBEGIN#### */ +/* */ +/* Author(s): nickg, jskov */ +/* Contributors: nickg, jskov */ +/* Date: 1999-03-23 */ +/* Purpose: HAL diagnostic output */ +/* Description: Implementations of HAL diagnostic output support. */ +/* */ +/*####DESCRIPTIONEND#### */ +/* */ +/*============================================================================= */ + +/*----------------------------------------------------------------------------- */ +/* Cogent board specific LCD code */ + +#include <common.h> +#include <stdarg.h> +#include <board/cogent/lcd.h> + +static char lines[2][LCD_LINE_LENGTH+1]; +static int curline; +static int linepos; +static int heartbeat_active; +/* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */ +/* pad to the right with spaces if necessary */ +static char init_line0[LCD_LINE_LENGTH+1] = "U-Boot Cogent "; +static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000"; + +static inline unsigned char +lcd_read_status(cma_mb_lcd *clp) +{ + /* read the Busy Status Register */ + return (cma_mb_reg_read(&clp->lcd_bsr)); +} + +static inline void +lcd_wait_not_busy(cma_mb_lcd *clp) +{ + /* + * wait for not busy + * Note: It seems that the LCD isn't quite ready to process commands + * when it clears the BUSY flag. Reading the status address an extra + * time seems to give it enough breathing room. + */ + + while (lcd_read_status(clp) & LCD_STAT_BUSY) + ; + + (void)lcd_read_status(clp); +} + +static inline void +lcd_write_command(cma_mb_lcd *clp, unsigned char cmd) +{ + lcd_wait_not_busy(clp); + + /* write the Command Register */ + cma_mb_reg_write(&clp->lcd_cmd, cmd); +} + +static inline void +lcd_write_data(cma_mb_lcd *clp, unsigned char data) +{ + lcd_wait_not_busy(clp); + + /* write the Current Character Register */ + cma_mb_reg_write(&clp->lcd_ccr, data); +} + +static inline void +lcd_dis(int addr, char *string) +{ + cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE; + int pos, linelen; + + linelen = LCD_LINE_LENGTH; + if (heartbeat_active && addr == LCD_LINE0) + linelen--; + + lcd_write_command(clp, LCD_CMD_ADD + addr); + for (pos = 0; *string != '\0' && pos < linelen; pos++) + lcd_write_data(clp, *string++); +} + +void +lcd_init(void) +{ + cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE; + int i; + + /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */ + lcd_write_command(clp, LCD_CMD_MODE); + + /* turn the LCD display on */ + lcd_write_command(clp, LCD_CMD_DON); + + curline = 0; + linepos = 0; + + for (i = 0; i < LCD_LINE_LENGTH; i++) { + lines[0][i] = init_line0[i]; + lines[1][i] = init_line1[i]; + } + + lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0; + + lcd_dis(LCD_LINE0, lines[0]); + lcd_dis(LCD_LINE1, lines[1]); + + printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH); +} + +void +lcd_write_char(const char c) +{ + int i, linelen; + + /* ignore CR */ + if (c == '\r') + return; + + linelen = LCD_LINE_LENGTH; + if (heartbeat_active && curline == 0) + linelen--; + + if (c == '\n') { + lcd_dis(LCD_LINE0, &lines[curline^1][0]); + lcd_dis(LCD_LINE1, &lines[curline][0]); + + /* Do a line feed */ + curline ^= 1; + linelen = LCD_LINE_LENGTH; + if (heartbeat_active && curline == 0) + linelen--; + linepos = 0; + + for (i = 0; i < linelen; i++) + lines[curline][i] = ' '; + + return; + } + + /* Only allow to be output if there is room on the LCD line */ + if (linepos < linelen) + lines[curline][linepos++] = c; +} + +void +lcd_flush(void) +{ + lcd_dis(LCD_LINE1, &lines[curline][0]); +} + +void +lcd_write_string(const char *s) +{ + char *p; + + for (p = (char *)s; *p != '\0'; p++) + lcd_write_char(*p); +} + +void +lcd_printf(const char *fmt, ...) +{ + va_list args; + char buf[CFG_PBSIZE]; + + va_start(args, fmt); + (void)vsprintf(buf, fmt, args); + va_end(args); + + lcd_write_string(buf); +} + +void +lcd_heartbeat(void) +{ + cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE; +#if 0 + static char rotchars[] = { '|', '/', '-', '\\' }; +#else + /* HD44780 Rom Code A00 has no backslash */ + static char rotchars[] = { '|', '/', '-', '\315' }; +#endif + static int rotator_index = 0; + + heartbeat_active = 1; + + /* write the address */ + lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1)); + + /* write the next char in the sequence */ + lcd_write_data(clp, rotchars[rotator_index]); + + if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0])) + rotator_index = 0; +} diff --git a/board/cogent/lcd.h b/board/cogent/lcd.h new file mode 100644 index 0000000..1056eea --- /dev/null +++ b/board/cogent/lcd.h @@ -0,0 +1,84 @@ +/* most of this is taken from the file */ +/* hal/powerpc/cogent/current/src/hal_diag.c in the */ +/* Cygnus eCos source. Here is the copyright notice: */ +/* */ +/*============================================================================= */ +/* */ +/* hal_diag.c */ +/* */ +/* HAL diagnostic output code */ +/* */ +/*============================================================================= */ +/*####COPYRIGHTBEGIN#### */ +/* */ +/* ------------------------------------------- */ +/* The contents of this file are subject to the Cygnus eCos Public License */ +/* Version 1.0 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://sourceware.cygnus.com/ecos */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the */ +/* License for the specific language governing rights and limitations under */ +/* the License. */ +/* */ +/* The Original Code is eCos - Embedded Cygnus Operating System, released */ +/* September 30, 1998. */ +/* */ +/* The Initial Developer of the Original Code is Cygnus. Portions created */ +/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. */ +/* ------------------------------------------- */ +/* */ +/*####COPYRIGHTEND#### */ +/*============================================================================= */ +/*#####DESCRIPTIONBEGIN#### */ +/* */ +/* Author(s): nickg, jskov */ +/* Contributors: nickg, jskov */ +/* Date: 1999-03-23 */ +/* Purpose: HAL diagnostic output */ +/* Description: Implementations of HAL diagnostic output support. */ +/* */ +/*####DESCRIPTIONEND#### */ +/* */ +/*============================================================================= */ + +/* FEMA 162B 16 character x 2 line LCD */ + +/* status register bit definitions */ +#define LCD_STAT_BUSY 0x80 /* 1 = display busy */ +#define LCD_STAT_ADD 0x7F /* bits 0-6 return current display address */ + +/* command register definitions */ +#define LCD_CMD_RST 0x01 /* clear entire display and reset display addr */ +#define LCD_CMD_HOME 0x02 /* reset display address and reset any shifting */ +#define LCD_CMD_ECL 0x04 /* move cursor left one pos on next data write */ +#define LCD_CMD_ESL 0x05 /* shift display left one pos on next data write */ +#define LCD_CMD_ECR 0x06 /* move cursor right one pos on next data write */ +#define LCD_CMD_ESR 0x07 /* shift disp right one pos on next data write */ +#define LCD_CMD_DOFF 0x08 /* display off, cursor off, blinking off */ +#define LCD_CMD_BL 0x09 /* blink character at current cursor position */ +#define LCD_CMD_CUR 0x0A /* enable cursor on */ +#define LCD_CMD_DON 0x0C /* turn display on */ +#define LCD_CMD_CL 0x10 /* move cursor left one position */ +#define LCD_CMD_SL 0x14 /* shift display left one position */ +#define LCD_CMD_CR 0x18 /* move cursor right one position */ +#define LCD_CMD_SR 0x1C /* shift display right one position */ +#define LCD_CMD_MODE 0x38 /* sets 8 bits, 2 lines, 5x7 characters */ +#define LCD_CMD_ACG 0x40 /* bits 0-5 sets character generator address */ +#define LCD_CMD_ADD 0x80 /* bits 0-6 sets display data addr to line 1 + */ + +/* LCD status values */ +#define LCD_OK 0x00 +#define LCD_ERR 0x01 + +#define LCD_LINE0 0x00 +#define LCD_LINE1 0x40 + +#define LCD_LINE_LENGTH 16 + +extern void lcd_init(void); +extern void lcd_write_char(const char); +extern void lcd_flush(void); +extern void lcd_write_string(const char *); +extern void lcd_printf(const char *, ...); diff --git a/board/cray/L1/flash.c b/board/cray/L1/flash.c new file mode 100644 index 0000000..6d66905 --- /dev/null +++ b/board/cray/L1/flash.c @@ -0,0 +1,471 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * 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 July 20, 2001 + * Strip down to support ONLY the AMD29F032B. + * Dave Updegraff - Cray, Inc. dave@cray.com + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +/* The flash chip we use... */ +#define AMD_ID_F032B 0x41 /* 29F032B ID 32 Mbit,64 64Kx8 sectors */ +#define FLASH_AM320B 0x0009 + + +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); + +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned char + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0, size_b1; + int i; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } + + /* Only one bank */ + if (CFG_MAX_FLASH_BANKS == 1) + { + /* Setup offsets */ + flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); + +#if 0 + /* Monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, + FLASH_BASE0_PRELIM, + FLASH_BASE0_PRELIM+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif + size_b1 = 0 ; + flash_info[0].size = size_b0; + } + + return (size_b0 + size_b1); +} + + + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + /* set up sector start address table */ + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); +} + +/*----------------------------------------------------------------------- + */ +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; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM320B:printf ("AM29F032B (32 Mbit 64x64KB uniform sectors)\n"); + break; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + /* + * Check if whole sector is erased + */ + if (i != (info->sector_count-1)) + size = info->start[i+1] - info->start[i]; + else + size = info->start[0] + info->size - info->start[i]; + erased = 1; + flash = (volatile unsigned long *)info->start[i]; + size = size >> 2; /* divide by 4 for longword access */ + for (k=0; k<size; k++) + { + if (*flash++ != 0xffffffff) + { + erased = 0; + break; + } + } + + if ((i % 5) == 0) + printf ("\n "); + + printf (" %08lX%s%s", + info->start[i], + erased ? " E" : " ", + info->protect[i] ? "RO " : " " + ); + } + printf ("\n"); +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + FLASH_WORD_SIZE value; + ulong base = (ulong)addr; + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr; + + /* Write auto select command: read Manufacturer ID */ + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090; + + value = addr2[0]; + + switch (value) { + case (FLASH_WORD_SIZE)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + + value = addr2[1]; /* device ID */ + + switch (value) { + case (FLASH_WORD_SIZE)AMD_ID_F032B: + info->flash_id += FLASH_AM320B; + info->sector_count = 64; + info->size = 0x0400000; /* => 4 MB */ + break; + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + + /* set up sector start address table */ + for (i = 0; i < info->sector_count; 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]); + info->protect[i] = addr2[2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr2 = (FLASH_WORD_SIZE *)info->start[0]; + *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + } + + 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 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; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr2 = (FLASH_WORD_SIZE *)(info->start[sect]); + printf("Erasing sector %p\n", addr2); + + 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 */ + 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); + + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data; + ulong start; + int flag; + int i; + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile FLASH_WORD_SIZE *)dest) & + (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++) + { + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0; + + dest2[i] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != + (data2[i] & (FLASH_WORD_SIZE)0x00800080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + } + + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/cray/L1/init.S b/board/cray/L1/init.S new file mode 100644 index 0000000..acc5205 --- /dev/null +++ b/board/cray/L1/init.S @@ -0,0 +1,147 @@ +/*------------------------------------------------------------------------------+ */ +/* */ +/* 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 and SRAM */ +/* Bank 1 - NVRAM/RTC */ +/* Bank 2 - Keyboard/Mouse controller */ +/* Bank 3 - IR controller */ +/* Bank 4 - not used */ +/* Bank 5 - not used */ +/* Bank 6 - not used */ +/* Bank 7 - FPGA registers */ +/*-----------------------------------------------------------------------------#include <config.h> */ +#include <ppc4xx.h> + +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +/* CRAY - L1: only nominally a 'walnut', since ext.Bus.Cntlr is all empty */ +/* except for #1 which we use for DMA'ing to IOCA-like things, so the */ +/* control registers to set that up are determined by what we've */ +/* empirically discovered work there. */ + + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + mflr r4 /* save link register */ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + mtlr r4 /* restore link register */ + addi r4,0,14 /* set ctr to 10; used to prefetch */ + mtctr r4 /* 10 cache lines to fit this function */ + /* in cache (gives us 8x10=80 instrctns) */ +..ebcloop: + icbt r0,r3 /* prefetch cache line for addr in r3 */ + addi r3,r3,32 /* move to next cache line */ + bdnz ..ebcloop /* continue for 10 cache lines */ + + /*------------------------------------------------------------------- */ + /* Delay to ensure all accesses to ROM are complete before changing */ + /* bank 0 timings. 200usec should be enough. */ + /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ + /*------------------------------------------------------------------- */ + addis r3,0,0x0 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + + /*---------------------------------------------------------------------- */ + /* Peripheral Bank 0 (Flash) initialization */ + /*---------------------------------------------------------------------- */ + /* 0x7F8FFE80 slowest boot */ + 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 + addis r4,0,0xFFC5 /* BAS=0xFFC,BS=0x4(4MB),BU=0x3(R/W), */ + ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ + mtdcr ebccfgd,r4 + + blr + + /*---------------------------------------------------------------------- */ + /* Peripheral Bank 1 (NVRAM/RTC) initialization */ + /* CRAY:the L1 has NOT this bank, it is tied to SV2/IOCA/etc/ instead */ + /* and we do DMA on it. The ConfigurationRegister part is threfore */ + /* almost arbitrary, except that our linux driver needs to know the */ + /* address, but it can query, it.. */ + /* */ + /* The AccessParameter is CRITICAL, */ + /* thouch, since it needs to agree with the electrical timings on the */ + /* IOCA parallel interface. That value is: 0x0185,4380 */ + /* BurstModeEnable BME=0 */ + /* TransferWait TWT=3 */ + /* ChipSelectOnTiming CSN=1 */ + /* OutputEnableOnTimimg OEN=1 */ + /* WriteByteEnableOnTiming WBN=1 */ + /* WriteByteEnableOffTiming WBF=0 */ + /* TransferHold TH=1 */ + /* ReadyEnable RE=1 */ + /* SampleOnReady SOR=1 */ + /* ByteEnableMode BEM=0 */ + /* ParityEnable PEN=0 */ + /* all reserved bits=0 */ + /*---------------------------------------------------------------------- */ + /*---------------------------------------------------------------------- */ + addi r4,0,pb1ap + mtdcr ebccfga,r4 + addis r4,0,0x0185 /* hiword */ + ori r4,r4,0x4380 /* loword */ + mtdcr ebccfgd,r4 + + addi r4,0,pb1cr + mtdcr ebccfga,r4 + addis r4,0,0xF001 /* BAS=0xF00,BS=0x0(1MB),BU=0x3(R/W), */ + ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ + mtdcr ebccfgd,r4 + + blr + +/*----------------------------------------------------------------------------- */ +/* Function: sdram_init */ +/* Description: Configures SDRAM memory banks. */ +/* NOTE: for CrayL1 we have ECC memory, so enable it. */ +/*....now done in C in L1.c:init_sdram for readability. */ +/*----------------------------------------------------------------------------- */ + .globl sdram_init + +sdram_init: + blr diff --git a/board/dnp1110/config.mk b/board/dnp1110/config.mk new file mode 100644 index 0000000..72ba595 --- /dev/null +++ b/board/dnp1110/config.mk @@ -0,0 +1,17 @@ +# +# DNP/1110 board with SA1100 cpu +# +# http://www.dilnetpc.com +# + +# +# DILNETPC has 1 banks of 32 MB DRAM +# +# c000'0000 +# +# Linux-Kernel is expected to be at c000'8000, entry c000'8000 +# +# we load ourself to c1f0'0000, the upper 1 MB of the first (only) bank +# + +TEXT_BASE = 0xc1f00000 diff --git a/board/dnp1110/memsetup.S b/board/dnp1110/memsetup.S new file mode 100644 index 0000000..bebd697 --- /dev/null +++ b/board/dnp1110/memsetup.S @@ -0,0 +1,96 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* some parameters for the board */ + +MEM_BASE: .long 0xa0000000 +MEM_START: .long 0xc0000000 + +#define MDCNFG 0x00 +#define MDCAS0 0x04 +#define MDCAS1 0x08 +#define MDCAS2 0x0c +#define MSC0 0x10 +#define MSC1 0x14 +#define MECR 0x18 + +mdcas0: .long 0xc71c703f +mdcas1: .long 0xffc71c71 +mdcas2: .long 0xffffffff +/* mdcnfg: .long 0x0bb2bcbf */ +mdcnfg: .long 0x0334b22f @ alt +/* mcs0: .long 0xfff8fff8 */ +msc0: .long 0xad8c4888 @ alt +mecr: .long 0x00060006 +/* mecr: .long 0x994a994a @ alt */ + +/* setting up the memory */ + +.globl memsetup +memsetup: + ldr r0, MEM_BASE + + /* Setup the flash memory */ + ldr r1, msc0 + str r1, [r0, #MSC0] + + /* Set up the DRAM */ + + /* MDCAS0 */ + ldr r1, mdcas0 + str r1, [r0, #MDCAS0] + + /* MDCAS1 */ + ldr r1, mdcas1 + str r1, [r0, #MDCAS1] + + /* MDCAS2 */ + ldr r1, mdcas2 + str r1, [r0, #MDCAS2] + + /* MDCNFG */ + ldr r1, mdcnfg + str r1, [r0, #MDCNFG] + + /* Set up PCMCIA space */ + ldr r1, mecr + str r1, [r0, #MECR] + + /* Load something to activate bank */ + ldr r1, MEM_START + +.rept 8 + ldr r0, [r1] +.endr + + /* everything is fine now */ + mov pc, lr + diff --git a/board/ebony/flash.c b/board/ebony/flash.c new file mode 100644 index 0000000..6efd566 --- /dev/null +++ b/board/ebony/flash.c @@ -0,0 +1,736 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 Jun Gu <jung@artesyncp.com> + * Add support for Am29F016D and dynamic switch setting. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + + +#undef DEBUG +#ifdef DEBUG +#define DEBUGF(x...) printf(x) +#else +#define DEBUGF(x...) +#endif /* DEBUG */ + +#define BOOT_SMALL_FLASH 32 /* 00100000 */ +#define FLASH_ONBD_N 2 /* 00000010 */ +#define FLASH_SRAM_SEL 1 /* 00000001 */ + +#define BOOT_SMALL_FLASH_VAL 4 +#define FLASH_ONBD_N_VAL 2 +#define FLASH_SRAM_SEL_VAL 1 + + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +static unsigned long flash_addr_table[8][CFG_MAX_FLASH_BANKS] = { + {0xffc00000, 0xffe00000, 0xff880000}, /* 0:000: configuraton 3 */ + {0xffc00000, 0xffe00000, 0xff800000}, /* 1:001: configuraton 4 */ + {0xffc00000, 0xffe00000, 0x00000000}, /* 2:010: configuraton 7 */ + {0xffc00000, 0xffe00000, 0x00000000}, /* 3:011: configuraton 8 */ + {0xff800000, 0xffa00000, 0xfff80000}, /* 4:100: configuraton 1 */ + {0xff800000, 0xffa00000, 0xfff00000}, /* 5:101: configuraton 2 */ + {0xffc00000, 0xffe00000, 0x00000000}, /* 6:110: configuraton 5 */ + {0xffc00000, 0xffe00000, 0x00000000} /* 7:111: configuraton 6 */ +}; + +/*----------------------------------------------------------------------- + * 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); +#if 0 +static void flash_get_offsets (ulong base, flash_info_t *info); +#endif + +#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_WALNUT405 +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned char +#endif + +#ifdef CONFIG_EBONY +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned char +#endif + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) { + unsigned long total_b = 0; + unsigned long size_b[CFG_MAX_FLASH_BANKS]; + unsigned char * fpga_base = (unsigned char *)CFG_FPGA_BASE; + unsigned char switch_status; + unsigned short index = 0; + int i; + + + /* read FPGA base register FPGA_REG0 */ + switch_status = *fpga_base; + + /* check the bitmap of switch status */ + if (switch_status & BOOT_SMALL_FLASH) { + index += BOOT_SMALL_FLASH_VAL; + } + if (switch_status & FLASH_ONBD_N) { + index += FLASH_ONBD_N_VAL; + } + if (switch_status & FLASH_SRAM_SEL) { + index += FLASH_SRAM_SEL_VAL; + } + + DEBUGF("\n"); + DEBUGF("FLASH: Index: %d\n", index); + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + flash_info[i].sector_count = -1; + flash_info[i].size = 0; + + /* check whether the address is 0 */ + if (flash_addr_table[index][i] == 0) { + continue; + } + + /* call flash_get_size() to initialize sector address */ + size_b[i] = flash_get_size( + (vu_long *)flash_addr_table[index][i], &flash_info[i]); + flash_info[i].size = size_b[i]; + if (flash_info[i].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", + i, size_b[i], size_b[i]<<20); + flash_info[i].sector_count = -1; + flash_info[i].size = 0; + } + + total_b += flash_info[i].size; + } + + return total_b; +} + + + +/*----------------------------------------------------------------------- + */ +#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) || + (info->flash_id == FLASH_AMD016)) { + 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 /* 0 */ + +/*----------------------------------------------------------------------- + */ +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; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AMD016: printf ("AM29F016D (16 Mbit, uniform sector size)\n"); + break; + 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; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + /* + * Check if whole sector is erased + */ + if (i != (info->sector_count-1)) + size = info->start[i+1] - info->start[i]; + else + size = info->start[0] + info->size - info->start[i]; + erased = 1; + flash = (volatile unsigned long *)info->start[i]; + size = size >> 2; /* divide by 4 for longword access */ + for (k=0; k<size; k++) + { + if (*flash++ != 0xffffffff) + { + erased = 0; + break; + } + } + + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s%s", + info->start[i], + erased ? " E" : " ", + info->protect[i] ? "RO " : " " + ); + } + printf ("\n"); + return; + } + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * 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; + + DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr ); + + /* Write auto select command: read Manufacturer ID */ + udelay(10000); + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + udelay(1000); + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + udelay(1000); + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090; + udelay(1000); + +#ifdef CONFIG_ADCIOP + value = addr2[2]; +#else + value = addr2[0]; +#endif + + DEBUGF("FLASH MANUFACT: %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)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 */ + } + +#ifdef CONFIG_ADCIOP + value = addr2[0]; /* device ID */ + debug ("\ndev_code=%x\n", value); +#else + value = addr2[1]; /* device ID */ +#endif + + DEBUGF("\nFLASH DEVICEID: %x\n", value); + + switch (value) { + case (FLASH_WORD_SIZE)AMD_ID_F016D: + info->flash_id += FLASH_AMD016; + info->sector_count = 32; + info->size = 0x00200000; + break; /* => 2 MB */ + 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)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) || + (info->flash_id == FLASH_AMD016)) { + 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; + } + } + } + + /* 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 */ +#ifdef CONFIG_ADCIOP + addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); + info->protect[i] = addr2[4] & 1; +#else + addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) + info->protect[i] = 0; + else + info->protect[i] = addr2[2] & 1; +#endif + } + + /* + * 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 flash_erase (flash_info_t *info, int s_first, int s_last) + { + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *addr2; + int flag, prot, sect, l_sect; + int i; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr2 = (FLASH_WORD_SIZE *)(info->start[sect]); + printf("Erasing sector %p\n", addr2); + + 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 */ + } 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 */ + } + l_sect = sect; + /* + * Wait for each sector to complete, it's more + * reliable. According to AMD Spec, you must + * issue all erase commands within a specified + * timeout. This has been seen to fail, especially + * if printf()s are included (for debug)!! + */ + wait_for_DQ7(info, sect); + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + +#if 0 + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + wait_for_DQ7(info, l_sect); + + DONE: +#endif + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + + printf (" done\n"); + return 0; + } + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + + int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) + { + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); + } + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + static int write_word (flash_info_t * info, ulong dest, ulong data) + { + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]); + volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data; + ulong start; + int i; + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile FLASH_WORD_SIZE *) dest) & + (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) { + return (2); + } + + for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) { + int flag; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0; + + dest2[i] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) != + (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) { + + if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + } + + return (0); + } + +/*----------------------------------------------------------------------- + */ diff --git a/board/eltec/mhpc/config.mk b/board/eltec/mhpc/config.mk new file mode 100644 index 0000000..607ebbc --- /dev/null +++ b/board/eltec/mhpc/config.mk @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# MHPC boards +# + +TEXT_BASE = 0xfe000000 +/*TEXT_BASE = 0x00200000 */ + + + + + + + + + + + + + + + + diff --git a/board/eric/flash.c b/board/eric/flash.c new file mode 100644 index 0000000..c3f6e15 --- /dev/null +++ b/board/eric/flash.c @@ -0,0 +1,1130 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + + +#ifdef CFG_FLASH_16BIT +#define FLASH_WORD_SIZE unsigned short +#define FLASH_ID_MASK 0xFFFF +#else +#define FLASH_WORD_SIZE unsigned long +#define FLASH_ID_MASK 0xFFFFFFFF +#endif + +/*----------------------------------------------------------------------- + * Functions + */ +/* stolen from esteem192e/flash.c */ +ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info); + +#ifndef CFG_FLASH_16BIT +static int write_word (flash_info_t *info, ulong dest, ulong data); +#else +static int write_short (flash_info_t *info, ulong dest, ushort data); +#endif +static void flash_get_offsets (ulong base, flash_info_t *info); + + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0, size_b1; + int i; + uint pbcr; + unsigned long base_b0, base_b1; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } + + /* Only one bank */ + if (CFG_MAX_FLASH_BANKS == 1) + { + /* Setup offsets */ + flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); + + /* Monitor protection ON by default */ +#if 0 /* sand: */ + (void)flash_protect(FLAG_PROTECT_SET, + FLASH_BASE0_PRELIM-CFG_MONITOR_LEN+size_b0, + FLASH_BASE0_PRELIM-1+size_b0, + &flash_info[0]); +#else + (void)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((volatile FLASH_WORD_SIZE *)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((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]); + + flash_get_offsets (base_b0, &flash_info[0]); + + /* monitor protection ON by default */ +#if 0 /* sand: */ + (void)flash_protect(FLAG_PROTECT_SET, + FLASH_BASE0_PRELIM-CFG_MONITOR_LEN+size_b0, + FLASH_BASE0_PRELIM-1+size_b0, + &flash_info[0]); +#else + (void)flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif + + if (size_b1) { + /* Re-do sizing to get full correct info */ + size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)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 */ + return (size_b0 + size_b1); +} + + + +/*----------------------------------------------------------------------- + */ + +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + /* set up sector start adress table */ + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F320J3A || + (info->flash_id & FLASH_TYPEMASK) == FLASH_28F640J3A || + (info->flash_id & FLASH_TYPEMASK) == FLASH_28F128J3A) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * info->size/info->sector_count); + } + } else if (info->flash_id & FLASH_BTYPE) { + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + +#ifndef CFG_FLASH_16BIT + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00004000; + info->start[2] = base + 0x00008000; + info->start[3] = base + 0x0000C000; + info->start[4] = base + 0x00010000; + info->start[5] = base + 0x00014000; + info->start[6] = base + 0x00018000; + info->start[7] = base + 0x0001C000; + for (i = 8; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00020000) - 0x000E0000; + } + } + else { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00008000; + info->start[2] = base + 0x0000C000; + info->start[3] = base + 0x00010000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00020000) - 0x00060000; + } + } +#else + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00002000; + info->start[2] = base + 0x00004000; + info->start[3] = base + 0x00006000; + info->start[4] = base + 0x00008000; + info->start[5] = base + 0x0000A000; + info->start[6] = base + 0x0000C000; + info->start[7] = base + 0x0000E000; + for (i = 8; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00010000) - 0x00070000; + } + } + else { + /* 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; + } + } +#endif + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + +#ifndef CFG_FLASH_16BIT + info->start[i--] = base + info->size - 0x00004000; + info->start[i--] = base + info->size - 0x00008000; + info->start[i--] = base + info->size - 0x0000C000; + info->start[i--] = base + info->size - 0x00010000; + info->start[i--] = base + info->size - 0x00014000; + info->start[i--] = base + info->size - 0x00018000; + info->start[i--] = base + info->size - 0x0001C000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00020000; + } + + } else { + + info->start[i--] = base + info->size - 0x00008000; + info->start[i--] = base + info->size - 0x0000C000; + info->start[i--] = base + info->size - 0x00010000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00020000; + } + } +#else + 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 * 0x00010000; + } + + } 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; + } + } +#endif + } + + +} + +/*----------------------------------------------------------------------- + */ + +void flash_print_info (flash_info_t *info) +{ + int i; + uchar *boottype; + uchar botboot[]=", bottom boot sect)\n"; + uchar topboot[]=", top boot sector)\n"; + + 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_STM: printf ("STM "); break; + case FLASH_MAN_INTEL: printf ("INTEL "); break; + default: printf ("Unknown Vendor "); break; + } + + if (info->flash_id & 0x0001 ) { + boottype = botboot; + } else { + boottype = topboot; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM400B: printf ("AM29LV400B (4 Mbit%s",boottype); + break; + case FLASH_AM400T: printf ("AM29LV400T (4 Mbit%s",boottype); + break; + case FLASH_AM800B: printf ("AM29LV800B (8 Mbit%s",boottype); + break; + case FLASH_AM800T: printf ("AM29LV800T (8 Mbit%s",boottype); + break; + case FLASH_AM160B: printf ("AM29LV160B (16 Mbit%s",boottype); + break; + case FLASH_AM160T: printf ("AM29LV160T (16 Mbit%s",boottype); + break; + case FLASH_AM320B: printf ("AM29LV320B (32 Mbit%s",boottype); + break; + case FLASH_AM320T: printf ("AM29LV320T (32 Mbit%s",boottype); + break; + case FLASH_INTEL800B: printf ("INTEL28F800B (8 Mbit%s",boottype); + break; + case FLASH_INTEL800T: printf ("INTEL28F800T (8 Mbit%s",boottype); + break; + case FLASH_INTEL160B: printf ("INTEL28F160B (16 Mbit%s",boottype); + break; + case FLASH_INTEL160T: printf ("INTEL28F160T (16 Mbit%s",boottype); + break; + case FLASH_INTEL320B: printf ("INTEL28F320B (32 Mbit%s",boottype); + break; + case FLASH_INTEL320T: printf ("INTEL28F320T (32 Mbit%s",boottype); + break; + +#if 0 /* enable when devices are available */ + + case FLASH_INTEL640B: printf ("INTEL28F640B (64 Mbit%s",boottype); + break; + case FLASH_INTEL640T: printf ("INTEL28F640T (64 Mbit%s",boottype); + break; +#endif + case FLASH_28F320J3A: printf ("INTEL28F320J3A (32 Mbit%s",boottype); + break; + case FLASH_28F640J3A: printf ("INTEL28F640J3A (64 Mbit%s",boottype); + break; + case FLASH_28F128J3A: printf ("INTEL28F128J3A (128 Mbit%s",boottype); + break; + + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ +ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info) +{ + short i; + ulong base = (ulong)addr; + FLASH_WORD_SIZE value; + + /* Write auto select command: read Manufacturer ID */ + + +#ifndef CFG_FLASH_16BIT + + /* + * Note: if it is an AMD flash and the word at addr[0000] + * is 0x00890089 this routine will think it is an Intel + * flash device and may(most likely) cause trouble. + */ + + addr[0x0000] = 0x00900090; + if(addr[0x0000] != 0x00890089){ + addr[0x0555] = 0x00AA00AA; + addr[0x02AA] = 0x00550055; + addr[0x0555] = 0x00900090; +#else + + /* + * Note: if it is an AMD flash and the word at addr[0000] + * is 0x0089 this routine will think it is an Intel + * flash device and may(most likely) cause trouble. + */ + + addr[0x0000] = 0x0090; + + if(addr[0x0000] != 0x0089){ + addr[0x0555] = 0x00AA; + addr[0x02AA] = 0x0055; + addr[0x0555] = 0x0090; +#endif + } + value = addr[0]; + + switch (value) { + case (AMD_MANUFACT & FLASH_ID_MASK): + info->flash_id = FLASH_MAN_AMD; + break; + case (FUJ_MANUFACT & FLASH_ID_MASK): + info->flash_id = FLASH_MAN_FUJ; + break; + case (STM_MANUFACT & FLASH_ID_MASK): + info->flash_id = FLASH_MAN_STM; + break; + case (SST_MANUFACT & FLASH_ID_MASK): + info->flash_id = FLASH_MAN_SST; + break; + case (INTEL_MANUFACT & FLASH_ID_MASK): + info->flash_id = FLASH_MAN_INTEL; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + + } + + value = addr[1]; /* device ID */ + + switch (value) { + + case (AMD_ID_LV400T & FLASH_ID_MASK): + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (AMD_ID_LV400B & FLASH_ID_MASK): + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (AMD_ID_LV800T & FLASH_ID_MASK): + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (AMD_ID_LV800B & FLASH_ID_MASK): + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (AMD_ID_LV160T & FLASH_ID_MASK): + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (AMD_ID_LV160B & FLASH_ID_MASK): + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ +#if 0 /* enable when device IDs are available */ + case (AMD_ID_LV320T & FLASH_ID_MASK): + info->flash_id += FLASH_AM320T; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ + + case (AMD_ID_LV320B & FLASH_ID_MASK): + info->flash_id += FLASH_AM320B; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ +#endif + + case (INTEL_ID_28F800B3T & FLASH_ID_MASK): + info->flash_id += FLASH_INTEL800T; + info->sector_count = 23; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (INTEL_ID_28F800B3B & FLASH_ID_MASK): + info->flash_id += FLASH_INTEL800B; + info->sector_count = 23; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (INTEL_ID_28F160B3T & FLASH_ID_MASK): + info->flash_id += FLASH_INTEL160T; + info->sector_count = 39; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (INTEL_ID_28F160B3B & FLASH_ID_MASK): + info->flash_id += FLASH_INTEL160B; + info->sector_count = 39; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (INTEL_ID_28F320B3T & FLASH_ID_MASK): + info->flash_id += FLASH_INTEL320T; + info->sector_count = 71; + info->size = 0x00800000; + break; /* => 8 MB */ + + case (INTEL_ID_28F320B3B & FLASH_ID_MASK): + info->flash_id += FLASH_AM320B; + info->sector_count = 71; + info->size = 0x00800000; + break; /* => 8 MB */ + +#if 0 /* enable when devices are available */ + case (INTEL_ID_28F320B3T & FLASH_ID_MASK): + info->flash_id += FLASH_INTEL320T; + info->sector_count = 135; + info->size = 0x01000000; + break; /* => 16 MB */ + + case (INTEL_ID_28F320B3B & FLASH_ID_MASK): + info->flash_id += FLASH_AM320B; + info->sector_count = 135; + info->size = 0x01000000; + break; /* => 16 MB */ +#endif + case (INTEL_ID_28F320J3A & FLASH_ID_MASK): + info->flash_id += FLASH_28F320J3A; + info->sector_count = 32; + info->size = 0x00400000; + break; /* => 32 MBit */ + case (INTEL_ID_28F640J3A & FLASH_ID_MASK): + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x00800000; + break; /* => 64 MBit */ + case (INTEL_ID_28F128J3A & FLASH_ID_MASK): + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x01000000; + break; /* => 128 MBit */ + + default: + /* FIXME*/ + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + } + + flash_get_offsets(base, info); + + /* 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 */ + addr = (volatile FLASH_WORD_SIZE *)(info->start[i]); + info->protect[i] = addr[2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr = (volatile FLASH_WORD_SIZE *)info->start[0]; + if( (info->flash_id & 0xFF00) == FLASH_MAN_INTEL){ + *addr = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */ + } else { + *addr = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */ + } + } + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + + volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]); + int flag, prot, sect, l_sect, barf; + ulong start, now, last; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if ((info->flash_id == FLASH_UNKNOWN) || + ((info->flash_id > FLASH_AMD_COMP) && + ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){ + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + if(info->flash_id < FLASH_AMD_COMP) { +#ifndef CFG_FLASH_16BIT + addr[0x0555] = 0x00AA00AA; + addr[0x02AA] = 0x00550055; + addr[0x0555] = 0x00800080; + addr[0x0555] = 0x00AA00AA; + addr[0x02AA] = 0x00550055; +#else + addr[0x0555] = 0x00AA; + addr[0x02AA] = 0x0055; + addr[0x0555] = 0x0080; + addr[0x0555] = 0x00AA; + addr[0x02AA] = 0x0055; +#endif + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]); + addr[0] = (0x00300030 & FLASH_ID_MASK); + l_sect = sect; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]); + while ((addr[0] & (0x00800080&FLASH_ID_MASK)) != + (0x00800080&FLASH_ID_MASK) ) + { + 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 */ + serial_putc ('.'); + last = now; + } + } + +DONE: + /* reset to read mode */ + addr = (volatile FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */ + } else { + + + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + barf = 0; +#ifndef CFG_FLASH_16BIT + addr = (vu_long*)(info->start[sect]); + addr[0] = 0x00200020; + addr[0] = 0x00D000D0; + while(!(addr[0] & 0x00800080)); /* wait for error or finish */ + if( addr[0] & 0x003A003A) { /* check for error */ + barf = addr[0] & 0x003A0000; + if( barf ) { + barf >>=16; + } else { + barf = addr[0] & 0x0000003A; + } + } +#else + addr = (vu_short*)(info->start[sect]); + addr[0] = 0x0020; + addr[0] = 0x00D0; + while(!(addr[0] & 0x0080)); /* wait for error or finish */ + if( addr[0] & 0x003A) /* check for error */ + barf = addr[0] & 0x003A; +#endif + if(barf) { + printf("\nFlash error in sector at %lx\n",(unsigned long)addr); + if(barf & 0x0002) printf("Block locked, not erased.\n"); + if((barf & 0x0030) == 0x0030) + printf("Command Sequence error.\n"); + if((barf & 0x0030) == 0x0020) + printf("Block Erase error.\n"); + if(barf & 0x0008) printf("Vpp Low error.\n"); + rcode = 1; + } else printf("."); + l_sect = sect; + } + addr = (volatile FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */ + + } + + } + printf (" done\n"); + return rcode; +} + +/*----------------------------------------------------------------------- + */ + +/*flash_info_t *addr2info (ulong addr) +{ + flash_info_t *info; + int i; + + for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) { + if ((addr >= info->start[0]) && + (addr < (info->start[0] + info->size)) ) { + return (info); + } + } + + return (NULL); +} +*/ +/*----------------------------------------------------------------------- + * Copy memory to flash. + * Make sure all target addresses are within Flash bounds, + * and no protected sectors are hit. + * Returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - target range includes protected sectors + * 8 - target address not in Flash memory + */ + +/*int flash_write (uchar *src, ulong addr, ulong cnt) +{ + int i; + ulong end = addr + cnt - 1; + flash_info_t *info_first = addr2info (addr); + flash_info_t *info_last = addr2info (end ); + flash_info_t *info; + + if (cnt == 0) { + return (0); + } + + if (!info_first || !info_last) { + return (8); + } + + for (info = info_first; info <= info_last; ++info) { + ulong b_end = info->start[0] + info->size;*/ /* bank end addr */ +/* short s_end = info->sector_count - 1; + for (i=0; i<info->sector_count; ++i) { + ulong e_addr = (i == s_end) ? b_end : info->start[i + 1]; + + if ((end >= info->start[i]) && (addr < e_addr) && + (info->protect[i] != 0) ) { + return (4); + } + } + } + +*/ /* finally write data to flash */ +/* for (info = info_first; info <= info_last && cnt>0; ++info) { + ulong len; + + len = info->start[0] + info->size - addr; + if (len > cnt) + len = cnt; + if ((i = write_buff(info, src, addr, len)) != 0) { + return (i); + } + cnt -= len; + addr += len; + src += len; + } + return (0); +} +*/ +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ +#ifndef CFG_FLASH_16BIT + ulong cp, wp, data; + int l; +#else + ulong cp, wp; + ushort data; +#endif + int i, rc; + +#ifndef CFG_FLASH_16BIT + + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); + +#else + wp = (addr & ~1); /* get lower word aligned address */ + + /* + * handle unaligned start byte + */ + if (addr - wp) { + data = 0; + data = (data << 8) | *src++; + --cnt; + if ((rc = write_short(info, wp, data)) != 0) { + return (rc); + } + wp += 2; + } + + /* + * handle word aligned part + */ +/* l = 0; used for debuging */ + while (cnt >= 2) { + data = 0; + for (i=0; i<2; ++i) { + data = (data << 8) | *src++; + } + +/* if(!l){ + printf("%x",data); + l = 1; + } used for debuging */ + + if ((rc = write_short(info, wp, data)) != 0) { + return (rc); + } + wp += 2; + cnt -= 2; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<2; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_short(info, wp, data)); + + +#endif +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +#ifndef CFG_FLASH_16BIT +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long*)(info->start[0]); + ulong start,barf; + int flag; + + + /* Check if Flash is (sufficiently) erased */ + if ((*((vu_long *)dest) & data) != data) { + return (2); + } + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + if(info->flash_id > FLASH_AMD_COMP) { + /* AMD stuff */ + addr[0x0555] = 0x00AA00AA; + addr[0x02AA] = 0x00550055; + addr[0x0555] = 0x00A000A0; + } else { + /* intel stuff */ + *addr = 0x00400040; + } + *((vu_long *)dest) = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + + if(info->flash_id > FLASH_AMD_COMP) { + + while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + + } else { + + while(!(addr[0] & 0x00800080)){ /* wait for error or finish */ + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + + if( addr[0] & 0x003A003A) { /* check for error */ + barf = addr[0] & 0x003A0000; + if( barf ) { + barf >>=16; + } else { + barf = addr[0] & 0x0000003A; + } + printf("\nFlash write error at address %lx\n",(unsigned long)dest); + if(barf & 0x0002) printf("Block locked, not erased.\n"); + if(barf & 0x0010) printf("Programming error.\n"); + if(barf & 0x0008) printf("Vpp Low error.\n"); + return(2); + } + + + } + + return (0); + +} + +#else + +static int write_short (flash_info_t *info, ulong dest, ushort data) +{ + vu_short *addr = (vu_short*)(info->start[0]); + ulong start,barf; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*((vu_short *)dest) & data) != data) { + return (2); + } + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + if(info->flash_id < FLASH_AMD_COMP) { + /* AMD stuff */ + addr[0x0555] = 0x00AA; + addr[0x02AA] = 0x0055; + addr[0x0555] = 0x00A0; + } else { + /* intel stuff */ + *addr = 0x00D0; + *addr = 0x0040; + } + *((vu_short *)dest) = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + + if(info->flash_id < FLASH_AMD_COMP) { + /* AMD stuff */ + while ((*((vu_short *)dest) & 0x0080) != (data & 0x0080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + + } else { + /* intel stuff */ + while(!(addr[0] & 0x0080)){ /* wait for error or finish */ + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1); + } + + if( addr[0] & 0x003A) { /* check for error */ + barf = addr[0] & 0x003A; + printf("\nFlash write error at address %lx\n",(unsigned long)dest); + if(barf & 0x0002) printf("Block locked, not erased.\n"); + if(barf & 0x0010) printf("Programming error.\n"); + if(barf & 0x0008) printf("Vpp Low error.\n"); + return(2); + } + *addr = 0x00B0; + *addr = 0x0070; + while(!(addr[0] & 0x0080)){ /* wait for error or finish */ + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1); + } + + *addr = 0x00FF; + + } + + return (0); + +} + + +#endif + +/*----------------------------------------------------------------------- + */ + diff --git a/board/eric/init.S b/board/eric/init.S new file mode 100644 index 0000000..bdf90a5 --- /dev/null +++ b/board/eric/init.S @@ -0,0 +1,355 @@ +/*------------------------------------------------------------------------------+ */ +/* */ +/* 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. */ +/* */ +/*----------------------------------------------------------------------------- */ +#include <config.h> +#include <ppc4xx.h> + +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + + + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + mflr r4 /* save link register */ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + mtlr r4 /* restore link register */ + addi r4,0,14 /* set ctr to 10; used to prefetch */ + mtctr r4 /* 10 cache lines to fit this function */ + /* in cache (gives us 8x10=80 instrctns) */ +..ebcloop: + icbt r0,r3 /* prefetch cache line for addr in r3 */ + addi r3,r3,32 /* move to next cache line */ + bdnz ..ebcloop /* continue for 10 cache lines */ + + /*------------------------------------------------------------------- */ + /* Delay to ensure all accesses to ROM are complete before changing */ + /* bank 0 timings. 200usec should be enough. */ + /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ + /*------------------------------------------------------------------- */ + addis r3,0,0x0 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + /*----------------------------------------------------------------------- */ + /* Memory Bank 0 (Flash) initialization (from openbios) */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb0ap + mtdcr ebccfga,r4 + addis r4,0,CS0_AP@h + ori r4,r4,CS0_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb0cr + mtdcr ebccfga,r4 + addis r4,0,CS0_CR@h + ori r4,r4,CS0_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 1 (NVRAM/RTC) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb1ap + mtdcr ebccfga,r4 + addis r4,0,CS1_AP@h + ori r4,r4,CS1_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb1cr + mtdcr ebccfga,r4 + addis r4,0,CS1_CR@h + ori r4,r4,CS1_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 2 (A/D converter) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb2ap + mtdcr ebccfga,r4 + addis r4,0,CS2_AP@h + ori r4,r4,CS2_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb2cr + mtdcr ebccfga,r4 + addis r4,0,CS2_CR@h + ori r4,r4,CS2_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 3 (Ethernet PHY Reset) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb3ap + mtdcr ebccfga,r4 + addis r4,0,CS3_AP@h + ori r4,r4,CS3_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb3cr + mtdcr ebccfga,r4 + addis r4,0,CS3_CR@h + ori r4,r4,CS3_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 4 (PC-MIP PRSNT1#) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb4ap + mtdcr ebccfga,r4 + addis r4,0,CS4_AP@h + ori r4,r4,CS4_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb4cr + mtdcr ebccfga,r4 + addis r4,0,CS4_CR@h + ori r4,r4,CS4_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 5 (PC-MIP PRSNT2#) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb5ap + mtdcr ebccfga,r4 + addis r4,0,CS5_AP@h + ori r4,r4,CS5_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb5cr + mtdcr ebccfga,r4 + addis r4,0,CS5_CR@h + ori r4,r4,CS5_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 6 (CPU LED0) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb6ap + mtdcr ebccfga,r4 + addis r4,0,CS6_AP@h + ori r4,r4,CS6_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb6cr + mtdcr ebccfga,r4 + addis r4,0,CS6_CR@h + ori r4,r4,CS5_CR@l + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- */ + /* Memory Bank 7 (CPU LED1) initialization */ + /*----------------------------------------------------------------------- */ + + addi r4,0,pb7ap + mtdcr ebccfga,r4 + addis r4,0,CS7_AP@h + ori r4,r4,CS7_AP@l + mtdcr ebccfgd,r4 + + addi r4,0,pb7cr + mtdcr ebccfga,r4 + addis r4,0,CS7_CR@h + ori r4,r4,CS7_CR@l + mtdcr ebccfgd,r4 + +/* addis r4,r0,FPGA_BRDC@h */ +/* ori r4,r4,FPGA_BRDC@l */ +/* lbz r3,0(r4) //get FPGA board control reg */ +/* eieio */ +/* ori r3,r3,0x01 //set UART1 control to select CTS/RTS */ +/* stb r3,0(r4) */ + + nop /* pass2 DCR errata #8 */ + blr + +/*----------------------------------------------------------------------------- */ +/* Function: sdram_init */ +/* Description: Configures SDRAM memory banks on ERIC. */ +/* We do manually init our SDRAM. */ +/* If we have two SDRAM banks, simply undef SINGLE_BANK (ROLF :-) */ +/* It is assumed that a 32MB 12x8(2) SDRAM is used. */ +/*----------------------------------------------------------------------------- */ + .globl sdram_init + +sdram_init: + + mflr r31 + +#ifdef CFG_SDRAM_MANUALLY + /*------------------------------------------------------------------- */ + /* Set MB0CF for bank 0. (0-32MB) Address Mode 4 since 12x8(2) */ + /*------------------------------------------------------------------- */ + + addi r4,0,mem_mb0cf + mtdcr memcfga,r4 + addis r4,0,MB0CF@h + ori r4,r4,MB0CF@l + mtdcr memcfgd,r4 + + /*------------------------------------------------------------------- */ + /* Set MB1CF for bank 1. (32MB-64MB) Address Mode 4 since 12x8(2) */ + /*------------------------------------------------------------------- */ + + addi r4,0,mem_mb1cf + mtdcr memcfga,r4 + addis r4,0,MB1CF@h + ori r4,r4,MB1CF@l + mtdcr memcfgd,r4 + + /*------------------------------------------------------------------- */ + /* Set MB2CF for bank 2. off */ + /*------------------------------------------------------------------- */ + + addi r4,0,mem_mb2cf + mtdcr memcfga,r4 + addis r4,0,MB2CF@h + ori r4,r4,MB2CF@l + mtdcr memcfgd,r4 + + /*------------------------------------------------------------------- */ + /* Set MB3CF for bank 3. off */ + /*------------------------------------------------------------------- */ + + addi r4,0,mem_mb3cf + mtdcr memcfga,r4 + addis r4,0,MB3CF@h + ori r4,r4,MB3CF@l + mtdcr memcfgd,r4 + + /*------------------------------------------------------------------- */ + /* Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR. */ + /* To set the appropriate timings, we need to know the SDRAM speed. */ + /* We can use the PLB speed since the SDRAM speed is the same as */ + /* the PLB speed. The PLB speed is the FBK divider times the */ + /* 405GP reference clock, which on the Walnut board is 33Mhz. */ + /* Thus, if FBK div is 2, SDRAM is 66Mhz; if FBK div is 3, SDRAM is */ + /* 100Mhz; if FBK is 3, SDRAM is 133Mhz. */ + /* NOTE: The Walnut board supports SDRAM speeds of 66Mhz, 100Mhz, and */ + /* maybe 133Mhz. */ + /*------------------------------------------------------------------- */ + + mfdcr r5,strap /* determine FBK divider */ + /* via STRAP reg to calc PLB speed. */ + /* SDRAM speed is the same as the PLB */ + /* speed. */ + rlwinm r4,r5,4,0x3 /* get FBK divide bits */ + +..chk_66: + cmpi %cr0,0,r4,0x1 + bne ..chk_100 + addis r6,0,SDTR_66@h /* SDTR1 value for 66Mhz */ + ori r6,r6,SDTR_66@l + addis r7,0,RTR_66 /* RTR value for 66Mhz */ + b ..sdram_ok +..chk_100: + cmpi %cr0,0,r4,0x2 + bne ..chk_133 + addis r6,0,SDTR_100@h /* SDTR1 value for 100Mhz */ + ori r6,r6,SDTR_100@l + addis r7,0,RTR_100 /* RTR value for 100Mhz */ + b ..sdram_ok +..chk_133: + addis r6,0,0x0107 /* SDTR1 value for 133Mhz */ + ori r6,r6,0x4015 + addis r7,0,0x07F0 /* RTR value for 133Mhz */ + +..sdram_ok: + /*------------------------------------------------------------------- */ + /* Set SDTR1 */ + /*------------------------------------------------------------------- */ + addi r4,0,mem_sdtr1 + mtdcr memcfga,r4 + mtdcr memcfgd,r6 + + /*------------------------------------------------------------------- */ + /* Set RTR */ + /*------------------------------------------------------------------- */ + addi r4,0,mem_rtr + mtdcr memcfga,r4 + mtdcr memcfgd,r7 + + /*------------------------------------------------------------------- */ + /* Delay to ensure 200usec have elapsed since reset. Assume worst */ + /* case that the core is running 200Mhz: */ + /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ + /*------------------------------------------------------------------- */ + addis r3,0,0x0000 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp2: + bdnz ..spinlp2 /* spin loop */ + + /*------------------------------------------------------------------- */ + /* Set memory controller options reg, MCOPT1. */ + /* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst */ + /* read/prefetch. */ + /*------------------------------------------------------------------- */ + addi r4,0,mem_mcopt1 + mtdcr memcfga,r4 + addis r4,0,0x8080 /* set DC_EN=1 */ + ori r4,r4,0x0000 + mtdcr memcfgd,r4 + + /*------------------------------------------------------------------- */ + /* Delay to ensure 10msec have elapsed since reset. This is */ + /* required for the MPC952 to stabalize. Assume worst */ + /* case that the core is running 200Mhz: */ + /* 200,000,000 (cycles/sec) X .010 (sec) = 0x1E8480 cycles */ + /* This delay should occur before accessing SDRAM. */ + /*------------------------------------------------------------------- */ + addis r3,0,0x001E + ori r3,r3,0x8480 /* ensure 10msec have passed since reset */ + mtctr r3 +..spinlp3: + bdnz ..spinlp3 /* spin loop */ + +#else +/*fixme: do SDRAM Autoconfig from EEPROM here */ + +#endif + mtlr r31 /* restore lr */ + blr diff --git a/board/esd/ar405/flash.c b/board/esd/ar405/flash.c new file mode 100644 index 0000000..4fa6b27 --- /dev/null +++ b/board/esd/ar405/flash.c @@ -0,0 +1,126 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +/* + * include common flash code (for esd boards) + */ +#include "../common/flash.c" + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static void flash_get_offsets (ulong base, flash_info_t *info); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0, size_b1; + int i; + uint pbcr; + unsigned long base_b0, base_b1; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + base_b0 = FLASH_BASE0_PRELIM; + size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } + + base_b1 = FLASH_BASE1_PRELIM; + size_b1 = flash_get_size((vu_long *)base_b1, &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; + + return (size_b0 + size_b1); +} diff --git a/board/esd/canbt/flash.c b/board/esd/canbt/flash.c new file mode 100644 index 0000000..214948f --- /dev/null +++ b/board/esd/canbt/flash.c @@ -0,0 +1,84 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +/* + * include common flash code (for esd boards) + */ +#include "../common/flash.c" + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static void flash_get_offsets (ulong base, flash_info_t *info); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0; + int i; + uint pbcr; + unsigned long base_b0; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } + + /* Setup offsets */ + flash_get_offsets (-size_b0, &flash_info[0]); + + /* Re-do sizing to get full correct info */ + mtdcr(ebccfga, pb0cr); + pbcr = mfdcr(ebccfgd); + mtdcr(ebccfga, pb0cr); + base_b0 = -size_b0; + pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17); + mtdcr(ebccfgd, pbcr); + /* printf("pb1cr = %x\n", pbcr); */ + + /* Monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, + -CFG_MONITOR_LEN, + 0xffffffff, + &flash_info[0]); + + flash_info[0].size = size_b0; + + return (size_b0); +} diff --git a/board/esd/cpciiser4/flash.c b/board/esd/cpciiser4/flash.c new file mode 100644 index 0000000..214948f --- /dev/null +++ b/board/esd/cpciiser4/flash.c @@ -0,0 +1,84 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +/* + * include common flash code (for esd boards) + */ +#include "../common/flash.c" + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static void flash_get_offsets (ulong base, flash_info_t *info); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0; + int i; + uint pbcr; + unsigned long base_b0; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } + + /* Setup offsets */ + flash_get_offsets (-size_b0, &flash_info[0]); + + /* Re-do sizing to get full correct info */ + mtdcr(ebccfga, pb0cr); + pbcr = mfdcr(ebccfgd); + mtdcr(ebccfga, pb0cr); + base_b0 = -size_b0; + pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17); + mtdcr(ebccfgd, pbcr); + /* printf("pb1cr = %x\n", pbcr); */ + + /* Monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, + -CFG_MONITOR_LEN, + 0xffffffff, + &flash_info[0]); + + flash_info[0].size = size_b0; + + return (size_b0); +} diff --git a/board/esd/dasa_sim/eeprom.c b/board/esd/dasa_sim/eeprom.c new file mode 100644 index 0000000..59ef1d6 --- /dev/null +++ b/board/esd/dasa_sim/eeprom.c @@ -0,0 +1,181 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <command.h> + + +#define EEPROM_CAP 0x50000358 +#define EEPROM_DATA 0x5000035c + + +unsigned int eepromReadLong(int offs) +{ + unsigned int value; + volatile unsigned short ret; + int count; + + *(unsigned short *)EEPROM_CAP = offs; + + count = 0; + + for (;;) + { + count++; + ret = *(unsigned short *)EEPROM_CAP; + + if ((ret & 0x8000) != 0) + break; + } + + value = *(unsigned long *)EEPROM_DATA; + + return value; +} + + +unsigned char eepromReadByte(int offs) +{ + unsigned int valueLong; + unsigned char *ptr; + + valueLong = eepromReadLong(offs & ~3); + ptr = (unsigned char *)&valueLong; + + return ptr[offs & 3]; +} + + +void eepromWriteLong(int offs, unsigned int value) +{ + volatile unsigned short ret; + int count; + + count = 0; + + *(unsigned long *)EEPROM_DATA = value; + *(unsigned short *)EEPROM_CAP = 0x8000 + offs; + + for (;;) + { + count++; + ret = *(unsigned short *)EEPROM_CAP; + + if ((ret & 0x8000) == 0) + break; + } +} + + +void eepromWriteByte(int offs, unsigned char valueByte) +{ + unsigned int valueLong; + unsigned char *ptr; + + valueLong = eepromReadLong(offs & ~3); + ptr = (unsigned char *)&valueLong; + + ptr[offs & 3] = valueByte; + + eepromWriteLong(offs & ~3, valueLong); +} + + +void i2c_read (uchar *addr, int alen, uchar *buffer, int len) +{ + int i; + int len2, ptr; + + /* printf("\naddr=%x alen=%x buffer=%x len=%x", addr[0], addr[1], *(short *)addr, alen, buffer, len); // test-only */ + + ptr = *(short *)addr; + + /* + * Read till lword boundary + */ + len2 = 4 - (*(short *)addr & 0x0003); + for (i=0; i<len2; i++) + { + *buffer++ = eepromReadByte(ptr++); + } + + /* + * Read all lwords + */ + len2 = (len - len2) >> 2; + for (i=0; i<len2; i++) + { + *(unsigned int *)buffer = eepromReadLong(ptr); + buffer += 4; + ptr += 4; + } + + /* + * Read last bytes + */ + len2 = (*(short *)addr + len) & 0x0003; + for (i=0; i<len2; i++) + { + *buffer++ = eepromReadByte(ptr++); + } +} + +void i2c_write (uchar *addr, int alen, uchar *buffer, int len) +{ + int i; + int len2, ptr; + + /* printf("\naddr=%x alen=%x buffer=%x len=%x", addr[0], addr[1], *(short *)addr, alen, buffer, len); // test-only */ + + ptr = *(short *)addr; + + /* + * Write till lword boundary + */ + len2 = 4 - (*(short *)addr & 0x0003); + for (i=0; i<len2; i++) + { + eepromWriteByte(ptr++, *buffer++); + } + + /* + * Write all lwords + */ + len2 = (len - len2) >> 2; + for (i=0; i<len2; i++) + { + eepromWriteLong(ptr, *(unsigned int *)buffer); + buffer += 4; + ptr += 4; + } + + /* + * Write last bytes + */ + len2 = (*(short *)addr + len) & 0x0003; + for (i=0; i<len2; i++) + { + eepromWriteByte(ptr++, *buffer++); + } +} diff --git a/board/evb64260/ecctest.c b/board/evb64260/ecctest.c new file mode 100644 index 0000000..e7c58b3 --- /dev/null +++ b/board/evb64260/ecctest.c @@ -0,0 +1,91 @@ +#ifdef ECC_TEST +static inline void ecc_off(void) +{ + *(volatile int *)(INTERNAL_REG_BASE_ADDR+0x4b4) &= ~0x00200000; +} + +static inline void ecc_on(void) +{ + *(volatile int *)(INTERNAL_REG_BASE_ADDR+0x4b4) |= 0x00200000; +} + +static int putshex(const char *buf, int len) +{ + int i; + for (i=0;i<len;i++) { + printf("%02x", buf[i]); + } + return 0; +} + +static int char_memcpy(void *d, const void *s, int len) +{ + int i; + char *cd=d; + const char *cs=s; + for(i=0;i<len;i++) { + *(cd++)=*(cs++); + } + return 0; +} + +static int memory_test(char *buf) +{ + const char src[][16]={ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, + {0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, + {0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}, + {0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08}, + {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10}, + {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20}, + {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40}, + {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}, + {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55}, + {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa}, + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff} + }; + const int foo[] = {0}; + int i,j,a; + + printf("\ntest @ %d %p\n", foo[0], buf); + for(i=0;i<12;i++) { + for(a=0;a<8;a++) { + const char *s=src[i]+a; + int align=(unsigned)(s)&0x7; + /* ecc_off(); */ + memcpy(buf,s,8); + /* ecc_on(); */ + putshex(s,8); + if(memcmp(buf,s,8)) { + putc('\n'); + putshex(buf,8); + printf(" [FAIL] (%p) align=%d\n", s, align); + for(j=0;j<8;j++) { + s[j]==buf[j]?puts(" "):printf("%02x", (s[j])^(buf[j])); + } + putc('\n'); + } else { + printf(" [PASS] (%p) align=%d\n", s, align); + } + /* ecc_off(); */ + char_memcpy(buf,s,8); + /* ecc_on(); */ + putshex(s,8); + if(memcmp(buf,s,8)) { + putc('\n'); + putshex(buf,8); + printf(" [FAIL] (%p) align=%d\n", s, align); + for(j=0;j<8;j++) { + s[j]==buf[j]?puts(" "):printf("%02x", (s[j])^(buf[j])); + } + putc('\n'); + } else { + printf(" [PASS] (%p) align=%d\n", s, align); + } + } + } + + return 0; +} +#endif diff --git a/board/evb64260/eth.h b/board/evb64260/eth.h new file mode 100644 index 0000000..ecc3762 --- /dev/null +++ b/board/evb64260/eth.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2001 + * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * eth.h - header file for the polled mode GT ethernet driver + */ + +#ifndef __GT6426x_ETH_H__ +#define __GT6426x_ETH_H__ + +#include <asm/types.h> +#include <asm/io.h> +#include <asm/byteorder.h> +#include <common.h> + +typedef struct eth0_tx_desc_struct { + volatile __u32 bytecount_reserved; + volatile __u32 command_status; + volatile struct eth0_tx_desc_struct * next_desc; + /* Note - the following will not work for 64 bit addressing */ + volatile unsigned char * buff_pointer; +} eth0_tx_desc_single __attribute__ ((packed)); + +typedef struct eth0_rx_desc_struct { + volatile __u32 buff_size_byte_count; + volatile __u32 command_status; + volatile struct eth0_rx_desc_struct * next_desc; + volatile unsigned char * buff_pointer; +} eth0_rx_desc_single __attribute__ ((packed)); + +#define NT 20 /* Number of Transmit buffers */ +#define NR 20 /* Number of Receive buffers */ +#define MAX_BUFF_SIZE (1536+2*CACHE_LINE_SIZE) /* 1600 */ +#define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400 + +unsigned long TDN_ETH0 , RDN_ETH0; /* Rx/Tx current Descriptor Number*/ +unsigned int EVB64260_ETH0_irq; + +#define CLOSED 0 +#define OPENED 1 + +#define PORT_ETH0 0 + +extern eth0_tx_desc_single *eth0_tx_desc; +extern eth0_rx_desc_single *eth0_rx_desc; +extern char *eth0_tx_buffer; +extern char *eth0_rx_buffer[NR]; +extern char *eth_data; + +extern int gt6426x_eth_poll(void *v); +extern int gt6426x_eth_transmit(void *v, volatile char *p, unsigned int s); +extern void gt6426x_eth_disable(void *v); +extern int gt6426x_eth_probe(void *v, bd_t *bis); + +#endif /* __GT64260x_ETH_H__ */ diff --git a/board/evb64260/mpsc.c b/board/evb64260/mpsc.c new file mode 100644 index 0000000..31a6a0d --- /dev/null +++ b/board/evb64260/mpsc.c @@ -0,0 +1,864 @@ +/* + * (C) Copyright 2001 + * John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * mpsc.c - driver for console over the MPSC. + */ + +#include <common.h> +#include <config.h> +#include <asm/cache.h> + +#include <malloc.h> +#include "mpsc.h" + +int (*mpsc_putchar)(char ch) = mpsc_putchar_early; + +static volatile unsigned int *rx_desc_base=NULL; +static unsigned int rx_desc_index=0; +static volatile unsigned int *tx_desc_base=NULL; +static unsigned int tx_desc_index=0; + +/* local function declarations */ +static int galmpsc_connect(int channel, int connect); +static int galmpsc_route_serial(int channel, int connect); +static int galmpsc_route_rx_clock(int channel, int brg); +static int galmpsc_route_tx_clock(int channel, int brg); +static int galmpsc_write_config_regs(int mpsc, int mode); +static int galmpsc_config_channel_regs(int mpsc); +static int galmpsc_set_char_length(int mpsc, int value); +static int galmpsc_set_stop_bit_length(int mpsc, int value); +static int galmpsc_set_parity(int mpsc, int value); +static int galmpsc_enter_hunt(int mpsc); +static int galmpsc_set_brkcnt(int mpsc, int value); +static int galmpsc_set_tcschar(int mpsc, int value); +static int galmpsc_set_snoop(int mpsc, int value); +static int galmpsc_shutdown(int mpsc); + +static int galsdma_set_RFT(int channel); +static int galsdma_set_SFM(int channel); +static int galsdma_set_rxle(int channel); +static int galsdma_set_txle(int channel); +static int galsdma_set_burstsize(int channel, unsigned int value); +static int galsdma_set_RC(int channel, unsigned int value); + +static int galbrg_set_CDV(int channel, int value); +static int galbrg_enable(int channel); +static int galbrg_disable(int channel); +static int galbrg_set_clksrc(int channel, int value); +static int galbrg_set_CUV(int channel, int value); + +static void galsdma_enable_rx(void); + +/* static int galbrg_reset(int channel); */ + +#define SOFTWARE_CACHE_MANAGEMENT + +#ifdef SOFTWARE_CACHE_MANAGEMENT +#define FLUSH_DCACHE(a,b) if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));} +#define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));} +#define INVALIDATE_DCACHE(a,b) if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));} +#else +#define FLUSH_DCACHE(a,b) +#define FLUSH_AND_INVALIDATE_DCACHE(a,b) +#define INVALIDATE_DCACHE(a,b) +#endif + + +/* GT64240A errata: cant read MPSC/BRG registers... so make mirrors in ram for read/modify write */ +#define MIRROR_HACK ((struct _tag_mirror_hack *)&(gd->mirror_hack)) + +#define GT_REG_WRITE_MIRROR_G(a,d) {MIRROR_HACK->a ## _M = d; GT_REG_WRITE(a,d);} +#define GTREGREAD_MIRROR_G(a) (MIRROR_HACK->a ## _M) + +#define GT_REG_WRITE_MIRROR(a,i,g,d) {MIRROR_HACK->a ## _M[i] = d; GT_REG_WRITE(a + (i*g),d);} +#define GTREGREAD_MIRROR(a,i,g) (MIRROR_HACK->a ## _M[i]) + +/* make sure this isn't bigger than 16 long words (u-boot.h) */ +struct _tag_mirror_hack { + unsigned GALMPSC_PROTOCONF_REG_M[2]; /* 8008 */ + unsigned GALMPSC_CHANNELREG_1_M[2]; /* 800c */ + unsigned GALMPSC_CHANNELREG_2_M[2]; /* 8010 */ + unsigned GALBRG_0_CONFREG_M[2]; /* b200 */ + + unsigned GALMPSC_ROUTING_REGISTER_M; /* b400 */ + unsigned GALMPSC_RxC_ROUTE_M; /* b404 */ + unsigned GALMPSC_TxC_ROUTE_M; /* b408 */ + + unsigned int baudrate; /* current baudrate, for tsc delay calc */ +}; + +/* static struct _tag_mirror_hack *mh = NULL; */ + +/* special function for running out of flash. doesn't modify any + * global variables [josh] */ +int +mpsc_putchar_early(char ch) +{ + DECLARE_GLOBAL_DATA_PTR; + int mpsc=CHANNEL; + int temp=GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP); + galmpsc_set_tcschar(mpsc,ch); + GT_REG_WRITE(GALMPSC_CHANNELREG_2+(mpsc*GALMPSC_REG_GAP), temp|0x200); + +#define MAGIC_FACTOR (10*1000000) + + udelay(MAGIC_FACTOR / MIRROR_HACK->baudrate); + return 0; +} + +/* This is used after relocation, see serial.c and mpsc_init2 */ +static int +mpsc_putchar_sdma(char ch) +{ + volatile unsigned int *p; + unsigned int temp; + + + /* align the descriptor */ + p = tx_desc_base; + memset((void *)p, 0, 8 * sizeof(unsigned int)); + + /* fill one 64 bit buffer */ + /* word swap, pad with 0 */ + p[4] = 0; /* x */ + p[5] = (unsigned int)ch; /* x */ + + /* CHANGED completely according to GT64260A dox - NTL */ + p[0] = 0x00010001; /* 0 */ + p[1] = DESC_OWNER | DESC_FIRST | DESC_LAST; /* 4 */ + p[2] = 0; /* 8 */ + p[3] = (unsigned int)&p[4]; /* c */ + +#if 0 + p[9] = DESC_FIRST | DESC_LAST; + p[10] = (unsigned int)&p[0]; + p[11] = (unsigned int)&p[12]; +#endif + + FLUSH_DCACHE(&p[0], &p[8]); + + GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR+(CHANNEL*GALSDMA_REG_DIFF), + (unsigned int)&p[0]); + GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR+(CHANNEL*GALSDMA_REG_DIFF), + (unsigned int)&p[0]); + + temp = GTREGREAD(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF)); + temp |= (TX_DEMAND | TX_STOP); + GT_REG_WRITE(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF), temp); + + INVALIDATE_DCACHE(&p[1], &p[2]); + + while(p[1] & DESC_OWNER) { + udelay(100); + INVALIDATE_DCACHE(&p[1], &p[2]); + } + + return 0; +} + +char +mpsc_getchar(void) +{ + DECLARE_GLOBAL_DATA_PTR; + static unsigned int done = 0; + volatile char ch; + unsigned int len=0, idx=0, temp; + + volatile unsigned int *p; + + + do { + p=&rx_desc_base[rx_desc_index*8]; + + INVALIDATE_DCACHE(&p[0], &p[1]); + /* Wait for character */ + while (p[1] & DESC_OWNER){ + udelay(100); + INVALIDATE_DCACHE(&p[0], &p[1]); + } + + /* Handle error case */ + if (p[1] & (1<<15)) { + printf("oops, error: %08x\n", p[1]); + + temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,CHANNEL,GALMPSC_REG_GAP); + temp |= (1 << 23); + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2, CHANNEL,GALMPSC_REG_GAP, temp); + + /* Can't poll on abort bit, so we just wait. */ + udelay(100); + + galsdma_enable_rx(); + } + + /* Number of bytes left in this descriptor */ + len = p[0] & 0xffff; + + if (len) { + /* Where to look */ + idx = 5; + if (done > 3) idx = 4; + if (done > 7) idx = 7; + if (done > 11) idx = 6; + + INVALIDATE_DCACHE(&p[idx], &p[idx+1]); + ch = p[idx] & 0xff; + done++; + } + + if (done < len) { + /* this descriptor has more bytes still + * shift down the char we just read, and leave the + * buffer in place for the next time around + */ + p[idx] = p[idx] >> 8; + FLUSH_DCACHE(&p[idx], &p[idx+1]); + } + + if (done == len) { + /* nothing left in this descriptor. + * go to next one + */ + p[1] = DESC_OWNER | DESC_FIRST | DESC_LAST; + p[0] = 0x00100000; + FLUSH_DCACHE(&p[0], &p[1]); + /* Next descriptor */ + rx_desc_index = (rx_desc_index + 1) % RX_DESC; + done = 0; + } + } while (len==0); /* galileo bug.. len might be zero */ + + return ch; +} + +int +mpsc_test_char(void) +{ + volatile unsigned int *p=&rx_desc_base[rx_desc_index*8]; + + INVALIDATE_DCACHE(&p[1], &p[2]); + + if (p[1] & DESC_OWNER) return 0; + else return 1; +} + +int +mpsc_init(int baud) +{ + DECLARE_GLOBAL_DATA_PTR; + + memset(MIRROR_HACK, 0, sizeof(struct _tag_mirror_hack)); + MIRROR_HACK->GALMPSC_ROUTING_REGISTER_M=0x3fffffff; + + /* BRG CONFIG */ + galbrg_set_baudrate(CHANNEL, baud); +#ifdef CONFIG_ZUMA_V2 + galbrg_set_clksrc(CHANNEL,0x8); /* connect TCLK -> BRG */ +#else + galbrg_set_clksrc(CHANNEL,0); +#endif + galbrg_set_CUV(CHANNEL, 0); + galbrg_enable(CHANNEL); + + /* Set up clock routing */ + galmpsc_connect(CHANNEL, GALMPSC_CONNECT); + galmpsc_route_serial(CHANNEL, GALMPSC_CONNECT); + galmpsc_route_rx_clock(CHANNEL, CHANNEL); + galmpsc_route_tx_clock(CHANNEL, CHANNEL); + + /* reset MPSC state */ + galmpsc_shutdown(CHANNEL); + + /* SDMA CONFIG */ + galsdma_set_burstsize(CHANNEL, L1_CACHE_BYTES/8); /* in 64 bit words (8 bytes) */ + galsdma_set_txle(CHANNEL); + galsdma_set_rxle(CHANNEL); + galsdma_set_RC(CHANNEL, 0xf); + galsdma_set_SFM(CHANNEL); + galsdma_set_RFT(CHANNEL); + + /* MPSC CONFIG */ + galmpsc_write_config_regs(CHANNEL, GALMPSC_UART); + galmpsc_config_channel_regs(CHANNEL); + galmpsc_set_char_length(CHANNEL, GALMPSC_CHAR_LENGTH_8); /* 8 */ + galmpsc_set_parity(CHANNEL, GALMPSC_PARITY_NONE); /* N */ + galmpsc_set_stop_bit_length(CHANNEL, GALMPSC_STOP_BITS_1); /* 1 */ + + /* COMM_MPSC CONFIG */ +#ifdef SOFTWARE_CACHE_MANAGEMENT + galmpsc_set_snoop(CHANNEL, 0); /* disable snoop */ +#else + galmpsc_set_snoop(CHANNEL, 1); /* enable snoop */ +#endif + + return 0; +} + +void +mpsc_init2(void) +{ + int i; + + mpsc_putchar = mpsc_putchar_sdma; + + /* RX descriptors */ + rx_desc_base = (unsigned int *)malloc(((RX_DESC+1)*8) * + sizeof(unsigned int)); + + /* align descriptors */ + rx_desc_base = (unsigned int *) + (((unsigned int)rx_desc_base+32) & 0xFFFFFFF0); + + rx_desc_index = 0; + + memset((void *)rx_desc_base, 0, (RX_DESC*8)*sizeof(unsigned int)); + + for (i = 0; i < RX_DESC; i++) { + rx_desc_base[i*8 + 3] = (unsigned int)&rx_desc_base[i*8 + 4]; /* Buffer */ + rx_desc_base[i*8 + 2] = (unsigned int)&rx_desc_base[(i+1)*8]; /* Next descriptor */ + rx_desc_base[i*8 + 1] = DESC_OWNER | DESC_FIRST | DESC_LAST; /* Command & control */ + rx_desc_base[i*8] = 0x00100000; + } + rx_desc_base[(i-1)*8 + 2] = (unsigned int)&rx_desc_base[0]; + + FLUSH_DCACHE(&rx_desc_base[0], &rx_desc_base[RX_DESC*8]); + GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR+(CHANNEL*GALSDMA_REG_DIFF), + (unsigned int)&rx_desc_base[0]); + + /* TX descriptors */ + tx_desc_base = (unsigned int *)malloc(((TX_DESC+1)*8) * + sizeof(unsigned int)); + + /* align descriptors */ + tx_desc_base = (unsigned int *) + (((unsigned int)tx_desc_base+32) & 0xFFFFFFF0); + + tx_desc_index = -1; + + memset((void *)tx_desc_base, 0, (TX_DESC*8)*sizeof(unsigned int)); + + for (i = 0; i < TX_DESC; i++) { + tx_desc_base[i*8 + 5] = (unsigned int)0x23232323; + tx_desc_base[i*8 + 4] = (unsigned int)0x23232323; + tx_desc_base[i*8 + 3] = (unsigned int)&tx_desc_base[i*8 + 4]; + tx_desc_base[i*8 + 2] = (unsigned int)&tx_desc_base[(i+1)*8]; + tx_desc_base[i*8 + 1] = DESC_OWNER | DESC_FIRST | DESC_LAST; + + /* set sbytecnt and shadow byte cnt to 1 */ + tx_desc_base[i*8] = 0x00010001; + } + tx_desc_base[(i-1)*8 + 2] = (unsigned int)&tx_desc_base[0]; + + FLUSH_DCACHE(&tx_desc_base[0], &tx_desc_base[TX_DESC*8]); + + udelay(100); + + galsdma_enable_rx(); + + return; +} + +int +galbrg_set_baudrate(int channel, int rate) +{ + DECLARE_GLOBAL_DATA_PTR; + int clock; + + galbrg_disable(channel); + +#ifdef CONFIG_ZUMA_V2 + /* from tclk */ + clock = (CFG_BUS_HZ/(16*rate)) - 1; +#else + clock = (3686400/(16*rate)) - 1; +#endif + + galbrg_set_CDV(channel, clock); + + galbrg_enable(channel); + + MIRROR_HACK->baudrate = rate; + + return 0; +} + +/* ------------------------------------------------------------------ */ + +/* Below are all the private functions that no one else needs */ + +static int +galbrg_set_CDV(int channel, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP); + temp &= 0xFFFF0000; + temp |= (value & 0x0000FFFF); + GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG,channel,GALBRG_REG_GAP, temp); + + return 0; +} + +static int +galbrg_enable(int channel) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP); + temp |= 0x00010000; + GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP,temp); + + return 0; +} + +static int +galbrg_disable(int channel) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP); + temp &= 0xFFFEFFFF; + GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP,temp); + + return 0; +} + +static int +galbrg_set_clksrc(int channel, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG,channel, GALBRG_REG_GAP); + temp &= 0xFF83FFFF; + temp |= (value << 18); + GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG,channel, GALBRG_REG_GAP,temp); + + return 0; +} + +static int +galbrg_set_CUV(int channel, int value) +{ + GT_REG_WRITE(GALBRG_0_BTREG + (channel * GALBRG_REG_GAP), value); + + return 0; +} + +#if 0 +static int +galbrg_reset(int channel) +{ + unsigned int temp; + + temp = GTREGREAD(GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP)); + temp |= 0x20000; + GT_REG_WRITE(GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp); + + return 0; +} +#endif + +static int +galsdma_set_RFT(int channel) +{ + unsigned int temp; + + temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF)); + temp |= 0x00000001; + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp); + + return 0; +} + +static int +galsdma_set_SFM(int channel) +{ + unsigned int temp; + + temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF)); + temp |= 0x00000002; + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp); + + return 0; +} + +static int +galsdma_set_rxle(int channel) +{ + unsigned int temp; + + temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF)); + temp |= 0x00000040; + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp); + + return 0; +} + +static int +galsdma_set_txle(int channel) +{ + unsigned int temp; + + temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF)); + temp |= 0x00000080; + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp); + + return 0; +} + +static int +galsdma_set_RC(int channel, unsigned int value) +{ + unsigned int temp; + + temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF)); + temp &= ~0x0000003c; + temp |= (value << 2); + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp); + + return 0; +} + +static int +galsdma_set_burstsize(int channel, unsigned int value) +{ + unsigned int temp; + + temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF)); + temp &= 0xFFFFCFFF; + switch (value) { + case 8: + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), + (temp | (0x3 << 12))); + break; + + case 4: + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), + (temp | (0x2 << 12))); + break; + + case 2: + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), + (temp | (0x1 << 12))); + break; + + case 1: + GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), + (temp | (0x0 << 12))); + break; + + default: + return -1; + break; + } + + return 0; +} + +static int +galmpsc_connect(int channel, int connect) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR_G(GALMPSC_ROUTING_REGISTER); + + if ((channel == 0) && connect) + temp &= ~0x00000007; + else if ((channel == 1) && connect) + temp &= ~(0x00000007 << 6); + else if ((channel == 0) && !connect) + temp |= 0x00000007; + else + temp |= (0x00000007 << 6); + + /* Just in case... */ + temp &= 0x3fffffff; + + GT_REG_WRITE_MIRROR_G(GALMPSC_ROUTING_REGISTER, temp); + + return 0; +} + +static int +galmpsc_route_serial(int channel, int connect) +{ + unsigned int temp; + + temp = GTREGREAD(GALMPSC_SERIAL_MULTIPLEX); + + if ((channel == 0) && connect) + temp |= 0x00000100; + else if ((channel == 1) && connect) + temp |= 0x00001000; + else if ((channel == 0) && !connect) + temp &= ~0x00000100; + else + temp &= ~0x00001000; + + GT_REG_WRITE(GALMPSC_SERIAL_MULTIPLEX,temp); + + return 0; +} + +static int +galmpsc_route_rx_clock(int channel, int brg) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR_G(GALMPSC_RxC_ROUTE); + + if (channel == 0) + temp |= brg; + else + temp |= (brg << 8); + + GT_REG_WRITE_MIRROR_G(GALMPSC_RxC_ROUTE,temp); + + return 0; +} + +static int +galmpsc_route_tx_clock(int channel, int brg) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR_G(GALMPSC_TxC_ROUTE); + + if (channel == 0) + temp |= brg; + else + temp |= (brg << 8); + + GT_REG_WRITE_MIRROR_G(GALMPSC_TxC_ROUTE,temp); + + return 0; +} + +static int +galmpsc_write_config_regs(int mpsc, int mode) +{ + if (mode == GALMPSC_UART) { + /* Main config reg Low (Null modem, Enable Tx/Rx, UART mode) */ + GT_REG_WRITE(GALMPSC_MCONF_LOW + (mpsc*GALMPSC_REG_GAP), + 0x000004c4); + + /* Main config reg High (32x Rx/Tx clock mode, width=8bits */ + GT_REG_WRITE(GALMPSC_MCONF_HIGH +(mpsc*GALMPSC_REG_GAP), + 0x024003f8); + /* 22 2222 1111 */ + /* 54 3210 9876 */ + /* 0000 0010 0000 0000 */ + /* 1 */ + /* 098 7654 3210 */ + /* 0000 0011 1111 1000 */ + } else + return -1; + + return 0; +} + +static int +galmpsc_config_channel_regs(int mpsc) +{ + DECLARE_GLOBAL_DATA_PTR; + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, 0); + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_3+(mpsc*GALMPSC_REG_GAP), 1); + GT_REG_WRITE(GALMPSC_CHANNELREG_4+(mpsc*GALMPSC_REG_GAP), 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_5+(mpsc*GALMPSC_REG_GAP), 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_6+(mpsc*GALMPSC_REG_GAP), 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_7+(mpsc*GALMPSC_REG_GAP), 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_8+(mpsc*GALMPSC_REG_GAP), 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_9+(mpsc*GALMPSC_REG_GAP), 0); + GT_REG_WRITE(GALMPSC_CHANNELREG_10+(mpsc*GALMPSC_REG_GAP), 0); + + galmpsc_set_brkcnt(mpsc, 0x3); + galmpsc_set_tcschar(mpsc, 0xab); + + return 0; +} + +static int +galmpsc_set_brkcnt(int mpsc, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP); + temp &= 0x0000FFFF; + temp |= (value << 16); + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, temp); + + return 0; +} + +static int +galmpsc_set_tcschar(int mpsc, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP); + temp &= 0xFFFF0000; + temp |= value; + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, temp); + + return 0; +} + +static int +galmpsc_set_char_length(int mpsc, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP); + temp &= 0xFFFFCFFF; + temp |= (value << 12); + GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP, temp); + + return 0; +} + +static int +galmpsc_set_stop_bit_length(int mpsc, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP); + temp |= (value << 14); + GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP,temp); + + return 0; +} + +static int +galmpsc_set_parity(int mpsc, int value) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP); + if (value != -1) { + temp &= 0xFFF3FFF3; + temp |= ((value << 18) | (value << 2)); + temp |= ((value << 17) | (value << 1)); + } else { + temp &= 0xFFF1FFF1; + } + + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, temp); + + return 0; +} + +static int +galmpsc_enter_hunt(int mpsc) +{ + DECLARE_GLOBAL_DATA_PTR; + int temp; + + temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP); + temp |= 0x80000000; + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, temp); + + /* Should Poll on Enter Hunt bit, but the register is write-only */ + /* errata suggests pausing 100 system cycles */ + udelay(100); + + return 0; +} + + +static int +galmpsc_shutdown(int mpsc) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int temp; + + /* cause RX abort (clears RX) */ + temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP); + temp |= MPSC_RX_ABORT | MPSC_TX_ABORT; + temp &= ~MPSC_ENTER_HUNT; + GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP,temp); + + GT_REG_WRITE(GALSDMA_0_COM_REG, 0); + GT_REG_WRITE(GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT); + + /* shut down the MPSC */ + GT_REG_WRITE(GALMPSC_MCONF_LOW, 0); + GT_REG_WRITE(GALMPSC_MCONF_HIGH, 0); + GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG, mpsc, GALMPSC_REG_GAP,0); + + udelay(100); + + /* shut down the sdma engines. */ + /* reset config to default */ + GT_REG_WRITE(GALSDMA_0_CONF_REG, 0x000000fc); + + udelay(100); + + /* clear the SDMA current and first TX and RX pointers */ + GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR, 0); + GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR, 0); + GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR, 0); + + udelay(100); + + return 0; +} + +static void +galsdma_enable_rx(void) +{ + int temp; + + /* Enable RX processing */ + temp = GTREGREAD(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF)); + temp |= RX_ENABLE; + GT_REG_WRITE(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF), temp); + + galmpsc_enter_hunt(CHANNEL); +} + +static int +galmpsc_set_snoop(int mpsc, int value) +{ + int reg = mpsc ? MPSC_1_ADDRESS_CONTROL_LOW : MPSC_0_ADDRESS_CONTROL_LOW; + int temp=GTREGREAD(reg); + if(value) + temp |= (1<< 6) | (1<<14) | (1<<22) | (1<<30); + else + temp &= ~((1<< 6) | (1<<14) | (1<<22) | (1<<30)); + GT_REG_WRITE(reg, temp); + return 0; +} diff --git a/board/evb64260/zuma_pbb.c b/board/evb64260/zuma_pbb.c new file mode 100644 index 0000000..10c4845 --- /dev/null +++ b/board/evb64260/zuma_pbb.c @@ -0,0 +1,200 @@ +#include <common.h> +#include <malloc.h> + +#if (CONFIG_COMMANDS & CFG_CMD_BSP) +#include <command.h> +#include <cmd_bsp.h> +#endif + +#include <pci.h> +#include <galileo/pci.h> +#include "zuma_pbb.h" + +#undef DEBUG + +#define PAT_LO 0x00010203 +#define PAT_HI 0x04050607 + +static PBB_DMA_REG_MAP *zuma_pbb_reg = NULL; + +static char test_buf1[2048]; +static char test_buf2[2048]; + +int zuma_test_dma (int cmd, int size) +{ + static const char *const test_legend[] = { + "write", "verify", + "copy", "compare", + "write inc", "verify inc" + }; + register int i, j; + unsigned int p1 = ((unsigned int) test_buf1 + 0xff) & (~0xff); + unsigned int p2 = ((unsigned int) test_buf2 + 0xff) & (~0xff); + volatile unsigned int *ps = (unsigned int *) p1; + volatile unsigned int *pd = (unsigned int *) p2; + unsigned int funct, pat_lo = PAT_LO, pat_hi = PAT_HI; + DMA_INT_STATUS stat; + int ret = 0; + + if (!zuma_pbb_reg) { + printf ("not initted\n"); + return -1; + } + + if (cmd < 0 || cmd > 5) { + printf ("inv cmd %d\n", cmd); + return -1; + } + + if (cmd == 2 || cmd == 3) { + /* not implemented */ + return 0; + } + + if (size <= 0 || size > 1024) + size = 1024; + + size &= (~7); /* throw away bottom 3 bits */ + + p1 = ((unsigned int) test_buf1 + 0xff) & (~0xff); + p2 = ((unsigned int) test_buf2 + 0xff) & (~0xff); + + memset ((void *) p1, 0, size); + memset ((void *) p2, 0, size); + + for (i = 0; i < size / 4; i += 2) { + ps[i] = pat_lo; + ps[i + 1] = pat_hi; + if (cmd == 4 || cmd == 5) { + unsigned char *pl = (unsigned char *) &pat_lo; + unsigned char *ph = (unsigned char *) &pat_hi; + + for (j = 0; j < 4; j++) { + pl[j] += 8; + ph[j] += 8; + } + } + } + + funct = (1 << 31) | (cmd << 24) | (size); + + zuma_pbb_reg->int_mask.pci_bits.chan0 = + EOF_RX_FLAG | EOF_TX_FLAG | EOB_TX_FLAG; + + zuma_pbb_reg->debug_57 = PAT_LO; /* patl */ + zuma_pbb_reg->debug_58 = PAT_HI; /* path */ + + zuma_pbb_reg->debug_54 = cpu_to_le32 (p1); /* src 0x01b0 */ + zuma_pbb_reg->debug_55 = cpu_to_le32 (p2); /* dst 0x01b8 */ + zuma_pbb_reg->debug_56 = cpu_to_le32 (funct); /* func, 0x01c0 */ + + /* give DMA time to chew on things.. dont use DRAM or PCI */ + /* if you can avoid it. */ + do { + for (i = 0; i < 1000 * 10; i++); + } while (le32_to_cpu (zuma_pbb_reg->debug_56) & (1 << 31)); + + stat.word = zuma_pbb_reg->status.word; + zuma_pbb_reg->int_mask.word = 0; + + printf ("stat: %08x (%x)\n", stat.word, stat.pci_bits.chan0); + + printf ("func: %08x\n", le32_to_cpu (zuma_pbb_reg->debug_56)); + printf ("src @%08x: %08x %08x %08x %08x\n", p1, ps[0], ps[1], ps[2], + ps[3]); + printf ("dst @%08x: %08x %08x %08x %08x\n", p2, pd[0], pd[1], pd[2], + pd[3]); + printf ("func: %08x\n", le32_to_cpu (zuma_pbb_reg->debug_56)); + + + if (cmd == 0 || cmd == 4) { + /* this is a write */ + if (!(stat.pci_bits.chan0 & EOF_RX_FLAG) || /* not done */ + (memcmp ((void *) ps, (void *) pd, size) != 0)) { /* cmp error */ + for (i = 0; i < size / 4; i += 2) { + if ((ps[i] != pd[i]) || (ps[i + 1] != pd[i + 1])) { + printf ("s @%p:%08x %08x\n", &ps[i], ps[i], ps[i + 1]); + printf ("d @%p:%08x %08x\n", &pd[i], pd[i], pd[i + 1]); + } + } + ret = -1; + } + } else { + /* this is a verify */ + if (!(stat.pci_bits.chan0 & EOF_TX_FLAG) || /* not done */ + (stat.pci_bits.chan0 & EOB_TX_FLAG)) { /* cmp error */ + printf ("%08x: %08x %08x\n", + le32_to_cpu (zuma_pbb_reg->debug_63), + zuma_pbb_reg->debug_61, zuma_pbb_reg->debug_62); + ret = -1; + } + } + + printf ("%s cmd %d, %d bytes: %s!\n", test_legend[cmd], cmd, size, + (ret == 0) ? "PASSED" : "FAILED"); + return 0; +} + +void zuma_init_pbb (void) +{ + unsigned int iobase; + pci_dev_t dev = + pci_find_device (VENDOR_ID_ZUMA, DEVICE_ID_ZUMA_PBB, 0); + + if (dev == -1) { + printf ("no zuma pbb\n"); + return; + } + + pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &iobase); + + zuma_pbb_reg = + (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK); + + if (!zuma_pbb_reg) { + printf ("zuma pbb bar none! (hah hah, get it?)\n"); + return; + } + + zuma_pbb_reg->int_mask.word = 0; + + printf ("pbb @ %p v%d.%d, timestamp %08x\n", zuma_pbb_reg, + zuma_pbb_reg->version.pci_bits.rev_major, + zuma_pbb_reg->version.pci_bits.rev_minor, + zuma_pbb_reg->timestamp); + +} + +#if (CONFIG_COMMANDS & CFG_CMD_BSP) + +static int last_cmd = 4; /* write increment */ +static int last_size = 64; + +int +do_zuma_init_pbb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + zuma_init_pbb (); + return 0; +} + +int +do_zuma_test_dma (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + if (argc > 1) { + last_cmd = simple_strtoul (argv[1], NULL, 10); + } + if (argc > 2) { + last_size = simple_strtoul (argv[2], NULL, 10); + } + zuma_test_dma (last_cmd, last_size); + return 0; +} + +int +do_zuma_init_mbox (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + zuma_mbox_init (); + return 0; +} + +#endif /* CFG_CMD_BSP */ diff --git a/board/evb64260/zuma_pbb_mbox.c b/board/evb64260/zuma_pbb_mbox.c new file mode 100644 index 0000000..5131339 --- /dev/null +++ b/board/evb64260/zuma_pbb_mbox.c @@ -0,0 +1,187 @@ +#include <common.h> +#include <galileo/pci.h> +#include <net.h> +#include <pci.h> + +#include "zuma_pbb.h" +#include "zuma_pbb_mbox.h" + + +struct _zuma_mbox_dev zuma_mbox_dev; + + +static int zuma_mbox_write(struct _zuma_mbox_dev *dev, unsigned int data) +{ + unsigned int status, count = 0, i; + + status = (volatile int)le32_to_cpu(dev->sip->mbox_status); + + while((status & OUT_PENDING) && count < 1000) { + count++; + for(i=0;i<1000;i++); + status = (volatile int)le32_to_cpu(dev->sip->mbox_status); + } + if(count < 1000) { + /* if SET it means msg pending */ + /* printf("mbox real write %08x\n",data); */ + dev->sip->mbox_out = cpu_to_le32(data); + return 4; + } + + printf("mbox tx timeout\n"); + return 0; +} + +static int zuma_mbox_read(struct _zuma_mbox_dev *dev, unsigned int *data) +{ + unsigned int status, count = 0, i; + + status = (volatile int)le32_to_cpu(dev->sip->mbox_status); + + while(!(status & IN_VALID) && count < 1000) { + count++; + for(i=0;i<1000;i++); + status = (volatile int)le32_to_cpu(dev->sip->mbox_status); + } + if(count < 1000) { + /* if SET it means msg pending */ + *data=le32_to_cpu(dev->sip->mbox_in); + /*printf("mbox real read %08x\n", *data); */ + return 4; + } + printf("mbox rx timeout\n"); + return 0; +} + +static int zuma_mbox_do_one_mailbox(unsigned int out, unsigned int *in) +{ + int ret; + ret=zuma_mbox_write(&zuma_mbox_dev,out); + /*printf("write 0x%08x (%d bytes)\n", out, ret); */ + if(ret!=4) return -1; + ret=zuma_mbox_read(&zuma_mbox_dev,in); + /*printf("read 0x%08x (%d bytes)\n", *in, ret); */ + if(ret!=4) return -1; + return 0; +} + + +#define RET_IF_FAILED(x) if ((x) == -1) return -1 + +static int zuma_mbox_do_all_mailbox(void) +{ + unsigned int data_in; + unsigned short sdata_in; + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_START, &data_in)); + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_MACL, &data_in)); + memcpy(zuma_acc_mac+2,&data_in,4); + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_MACH, &data_in)); + sdata_in=data_in&0xffff; + memcpy(zuma_acc_mac,&sdata_in,2); + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_IP, &data_in)); + zuma_ip=data_in; + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_SLOT, &data_in)); + zuma_slot_bac=data_in>>3; + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_BAUD, &data_in)); + zuma_console_baud = data_in & 0xffff; + zuma_debug_baud = data_in >> 16; + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_ENG_PRV_MACL, &data_in)); + memcpy(zuma_prv_mac+2,&data_in,4); + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_ENG_PRV_MACH, &data_in)); + sdata_in=data_in&0xffff; + memcpy(zuma_prv_mac,&sdata_in,2); + + RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_DONE, &data_in)); + + return 0; +} + + +static void +zuma_mbox_dump(void) +{ + printf("ACC MAC=%04x%08x\n",*(unsigned short *)(&zuma_acc_mac),*(unsigned int *)((char *)&zuma_acc_mac+2)); + printf("PRV MAC=%04x%08x\n",*(unsigned short *)(&zuma_prv_mac),*(unsigned int *)((char *)&zuma_prv_mac+2)); + printf("slot:bac=%d:%d\n",(zuma_slot_bac>>2)&0xf, zuma_slot_bac & 0x3); + printf("BAUD1=%d BAUD2=%d\n",zuma_console_baud,zuma_debug_baud); +} + + +static void +zuma_mbox_setenv(void) +{ + unsigned char *data, buf[32]; + unsigned char save = 0; + + data = getenv("baudrate"); + + if(!data || (zuma_console_baud != simple_strtoul(data, NULL, 10))) { + sprintf(buf, "%6d", zuma_console_baud); + setenv("baudrate", buf); + save=1; + printf("baudrate doesn't match from mbox\n"); + } + + ip_to_string(zuma_ip, buf); + setenv("ipaddr", buf); + + sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x", + zuma_prv_mac[0], + zuma_prv_mac[1], + zuma_prv_mac[2], + zuma_prv_mac[3], + zuma_prv_mac[4], + zuma_prv_mac[5]); + setenv("ethaddr", buf); + + sprintf(buf,"%02x",zuma_slot_bac); + setenv("bacslot", buf); + + if(save) + saveenv(); +} + +/** + * zuma_mbox_init: + */ + +int zuma_mbox_init(void) +{ + unsigned int iobase; + memset(&zuma_mbox_dev, 0, sizeof(struct _zuma_mbox_dev)); + + zuma_mbox_dev.dev = pci_find_device(VENDOR_ID_ZUMA, DEVICE_ID_ZUMA_PBB, 0); + + if(zuma_mbox_dev.dev == -1) { + printf("no zuma pbb\n"); + return -1; + } + + pci_read_config_dword(zuma_mbox_dev.dev, PCI_BASE_ADDRESS_0, &iobase); + + zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK); + + zuma_mbox_dev.sip->int_mask.word=0; + + printf("pbb @ %p v%d.%d, timestamp %08x\n", zuma_mbox_dev.sip, + zuma_mbox_dev.sip->version.pci_bits.rev_major, + zuma_mbox_dev.sip->version.pci_bits.rev_minor, + zuma_mbox_dev.sip->timestamp); + + if (zuma_mbox_do_all_mailbox() == -1) { + printf("mailbox failed.. no ACC?\n"); + return -1; + } + + zuma_mbox_dump(); + + zuma_mbox_setenv(); + + return 0; +} diff --git a/board/fads/fads.c b/board/fads/fads.c new file mode 100644 index 0000000..3b97f51 --- /dev/null +++ b/board/fads/fads.c @@ -0,0 +1,876 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <config.h> +#include <mpc8xx.h> +#include "fads.h" + +/* ------------------------------------------------------------------------- */ + +#define _NOT_USED_ 0xFFFFFFFF + +#if defined(CONFIG_DRAM_50MHZ) +/* 50MHz tables */ +const uint dram_60ns[] = +{ 0x8fffec24, 0x0fffec04, 0x0cffec04, 0x00ffec04, + 0x00ffec00, 0x37ffec47, 0xffffffff, 0xffffffff, + 0x8fffec24, 0x0fffec04, 0x08ffec04, 0x00ffec0c, + 0x03ffec00, 0x00ffec44, 0x00ffcc08, 0x0cffcc44, + 0x00ffec0c, 0x03ffec00, 0x00ffec44, 0x00ffcc00, + 0x3fffc847, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06, + 0xffffcc85, 0xffffcc05, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +const uint dram_70ns[] = +{ 0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04, + 0x00ffcc00, 0x37ffcc47, 0xffffffff, 0xffffffff, + 0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04, + 0x00ffcc08, 0x0cffcc44, 0x00ffec0c, 0x03ffec00, + 0x00ffec44, 0x00ffcc08, 0x0cffcc44, 0x00ffec04, + 0x00ffec00, 0x3fffec47, 0xffffffff, 0xffffffff, + 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04, + 0x7fffcc06, 0xffffcc85, 0xffffcc05, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +const uint edo_60ns[] = +{ 0x8ffbec24, 0x0ff3ec04, 0x0cf3ec04, 0x00f3ec04, + 0x00f3ec00, 0x37f7ec47, 0xffffffff, 0xffffffff, + 0x8fffec24, 0x0ffbec04, 0x0cf3ec04, 0x00f3ec0c, + 0x0cf3ec00, 0x00f3ec4c, 0x0cf3ec00, 0x00f3ec4c, + 0x0cf3ec00, 0x00f3ec44, 0x03f3ec00, 0x3ff7ec47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06, + 0xffffcc85, 0xffffcc05, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +const uint edo_70ns[] = +{ 0x8ffbcc24, 0x0ff3cc04, 0x0cf3cc04, 0x00f3cc04, + 0x00f3cc00, 0x37f7cc47, 0xffffffff, 0xffffffff, + 0x8fffcc24, 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc0c, + 0x03f3cc00, 0x00f3cc44, 0x00f3ec0c, 0x0cf3ec00, + 0x00f3ec4c, 0x03f3ec00, 0x00f3ec44, 0x00f3cc00, + 0x33f7cc47, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c, + 0x0cafcc00, 0x33bfcc47, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04, + 0x7fffcc04, 0xffffcc86, 0xffffcc05, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +#elif defined(CONFIG_DRAM_25MHZ) + +/* 25MHz tables */ + +const uint dram_60ns[] = +{ 0x0fffcc04, 0x08ffcc00, 0x33ffcc47, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c, + 0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c, + 0x08ffcc00, 0x33ffcc47, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fafcc04, 0x08afcc00, 0x3fbfcc47, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00, + 0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00, + 0x31bfcc43, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +const uint dram_70ns[] = +{ 0x0fffec04, 0x08ffec04, 0x00ffec00, 0x3fffcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c, + 0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c, + 0x08ffcc00, 0x33ffcc47, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fafcc04, 0x08afcc00, 0x3fbfcc47, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00, + 0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00, + 0x31bfcc43, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +const uint edo_60ns[] = +{ 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0ffbcc04, 0x09f3cc0c, 0x09f3cc0c, 0x09f3cc0c, + 0x08f3cc00, 0x3ff7cc47, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fefcc04, 0x08afcc00, 0x07afcc48, 0x08afcc48, + 0x08afcc48, 0x39bfcc47, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + +const uint edo_70ns[] = +{ 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0ffbec04, 0x08f3ec04, 0x03f3ec48, 0x08f3cc00, + 0x0ff3cc4c, 0x08f3cc00, 0x0ff3cc4c, 0x08f3cc00, + 0x3ff7cc47, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x0fefcc04, 0x08afcc00, 0x07afcc4c, 0x08afcc00, + 0x07afcc4c, 0x08afcc00, 0x07afcc4c, 0x08afcc00, + 0x37bfcc47, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff }; + + +#else +#error dram not correct defined - use CONFIG_DRAM_25MHZ or CONFIG_DRAM_50MHZ +#endif + +/* ------------------------------------------------------------------------- */ + + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + uint k; + + puts ("Board: "); + +#ifdef CONFIG_FADS + k = (*((uint *)BCSR3) >> 24) & 0x3f; + + switch(k) { + case 0x03 : + case 0x20 : + case 0x21 : + case 0x22 : + case 0x23 : + case 0x24 : + case 0x3f : + puts ("FADS"); + break; + + default : + printf("unknown board (0x%02x)\n", k); + return -1; + } + + printf(" with db "); + + switch(k) { + case 0x03 : + puts ("MPC823"); + break; + case 0x20 : + puts ("MPC801"); + break; + case 0x21 : + puts ("MPC850"); + break; + case 0x22 : + puts ("MPC821, MPC860 / MPC860SAR / MPC860T"); + break; + case 0x23 : + puts ("MPC860SAR"); + break; + case 0x24 : + puts ("MPC860T"); + break; + case 0x3f : + puts ("MPC850SAR"); + break; + } + + printf(" rev "); + + k = (((*((uint *)BCSR3) >> 23) & 1) << 3) + | (((*((uint *)BCSR3) >> 19) & 1) << 2) + | (((*((uint *)BCSR3) >> 16) & 3)); + + switch(k) { + case 0x01 : + puts ("ENG or PILOT\n"); + break; + + default: + printf("unknown (0x%x)\n", k); + return -1; + } + + return 0; +#endif /* CONFIG_FADS */ + +#ifdef CONFIG_ADS + printf("ADS rev "); + + k = (((*((uint *)BCSR3) >> 23) & 1) << 3) + | (((*((uint *)BCSR3) >> 19) & 1) << 2) + | (((*((uint *)BCSR3) >> 16) & 3)); + + switch(k) { + case 0x00 : puts ("ENG - this board sucks, check the errata, not supported\n"); + return -1; + case 0x01 : puts ("PILOT - warning, read errata \n"); break; + case 0x02 : puts ("A - warning, read errata \n"); break; + case 0x03 : puts ("B \n"); break; + default : printf ("unknown revision (0x%x)\n", k); return -1; + } + + return 0; +#endif /* CONFIG_ADS */ + +} + +/* ------------------------------------------------------------------------- */ +int _draminit(uint base, uint noMbytes, uint edo, uint delay) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + + /* init upm */ + + switch(delay) + { + case 70: + { + if(edo) + { + upmconfig(UPMA, (uint *) edo_70ns, sizeof(edo_70ns)/sizeof(uint)); + } + else + { + upmconfig(UPMA, (uint *) dram_70ns, sizeof(dram_70ns)/sizeof(uint)); + } + + break; + } + + case 60: + { + if(edo) + { + upmconfig(UPMA, (uint *) edo_60ns, sizeof(edo_60ns)/sizeof(uint)); + } + else + { + upmconfig(UPMA, (uint *) dram_60ns, sizeof(dram_60ns)/sizeof(uint)); + } + + break; + } + + default : + return -1; + } + + memctl->memc_mptpr = 0x0400; /* divide by 16 */ + + switch(noMbytes) + { + + case 8: /* 8 Mbyte uses both CS3 and CS2 */ + { + memctl->memc_mamr = 0x13a01114; + memctl->memc_or3 = 0xffc00800; + memctl->memc_br3 = 0x00400081 + base; + memctl->memc_or2 = 0xffc00800; + break; + } + + case 4: /* 4 Mbyte uses only CS2 */ + { + memctl->memc_mamr = 0x13a01114; + memctl->memc_or2 = 0xffc00800; + break; + } + + case 32: /* 32 Mbyte uses both CS3 and CS2 */ + { + memctl->memc_mamr = 0x13b01114; + memctl->memc_or3 = 0xff000800; + memctl->memc_br3 = 0x01000081 + base; + memctl->memc_or2 = 0xff000800; + break; + } + + case 16: /* 16 Mbyte uses only CS2 */ + { +#ifdef CONFIG_ADS + memctl->memc_mamr = 0x60b21114; +#else + memctl->memc_mamr = 0x13b01114; +#endif + memctl->memc_or2 = 0xff000800; + break; + } + + default: + return -1; + } + + memctl->memc_br2 = 0x81 + base; /* use upma */ + return 0; +} + +/* ------------------------------------------------------------------------- */ + +void _dramdisable(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + + memctl->memc_br2 = 0x00000000; + memctl->memc_br3 = 0x00000000; + + /* maybe we should turn off upma here or something */ +} + +#if defined(CONFIG_SDRAM_100MHZ) + +/* ------------------------------------------------------------------------- */ +/* sdram table by Dan Malek */ + +/* This has the stretched early timing so the 50 MHz + * processor can make the 100 MHz timing. This will + * work at all processor speeds. + */ + +#define SDRAM_MPTPRVALUE 0x0400 + +#define SDRAM_MBMRVALUE0 0xc3802114 /* (16-14) 50 MHz */ +#define SDRAM_MBMRVALUE1 SDRAM_MBMRVALUE0 + +#define SDRAM_OR4VALUE 0xffc00a00 +#define SDRAM_BR4VALUE 0x000000c1 /* base address will be or:ed on */ + +#define SDRAM_MARVALUE 0x88 + +#define SDRAM_MCRVALUE0 0x80808111 /* run pattern 0x11 */ +#define SDRAM_MCRVALUE1 SDRAM_MCRVALUE0 + + +const uint sdram_table[] = +{ + /* single read. (offset 0 in upm RAM) */ + 0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x11adfc04, + 0xefbbbc00, 0x1ff77c45, 0xffffffff, 0xffffffff, + + /* burst read. (offset 8 in upm RAM) */ + 0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x10adfc04, + 0xf0affc00, 0xf0affc00, 0xf1affc00, 0xefbbbc00, + 0x1ff77c45, 0xeffbbc04, 0x1ff77c34, 0xefeabc34, + 0x1fb57c35, 0xffffffff, 0xffffffff, 0xffffffff, + + /* single write. (offset 18 in upm RAM) */ + 0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x01b93c04, + 0x1ff77c45, 0xffffffff, 0xffffffff, 0xffffffff, + + /* burst write. (offset 20 in upm RAM) */ + 0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x10ad7c00, + 0xf0affc00, 0xf0affc00, 0xe1bbbc04, 0x1ff77c45, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + + /* refresh. (offset 30 in upm RAM) */ + 0xeffafc84, 0x1ff5fc04, 0xfffffc04, 0xfffffc04, + 0xfffffc84, 0xfffffc07, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + + /* exception. (offset 3c in upm RAM) */ + 0xeffffc06, 0x1ffffc07, 0xffffffff, 0xffffffff }; + +#elif defined(CONFIG_SDRAM_50MHZ) + +/* ------------------------------------------------------------------------- */ +/* sdram table stolen from the fads manual */ +/* for chip MB811171622A-100 */ + +/* this table is for 32-50MHz operation */ + +#define _not_used_ 0xffffffff + +#define SDRAM_MPTPRVALUE 0x0400 + +#define SDRAM_MBMRVALUE0 0x80802114 /* refresh at 32MHz */ +#define SDRAM_MBMRVALUE1 0x80802118 + +#define SDRAM_OR4VALUE 0xffc00a00 +#define SDRAM_BR4VALUE 0x000000c1 /* base address will be or:ed on */ + +#define SDRAM_MARVALUE 0x88 + +#define SDRAM_MCRVALUE0 0x80808105 +#define SDRAM_MCRVALUE1 0x80808130 + +const uint sdram_table[] = +{ + /* single read. (offset 0 in upm RAM) */ + 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00, + 0x1ff77c47, + + /* MRS initialization (offset 5) */ + + 0x1ff77c34, 0xefeabc34, 0x1fb57c35, + + /* burst read. (offset 8 in upm RAM) */ + 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00, + 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, + _not_used_, _not_used_, _not_used_, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* single write. (offset 18 in upm RAM) */ + 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* burst write. (offset 20 in upm RAM) */ + 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00, + 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* refresh. (offset 30 in upm RAM) */ + 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04, + 0xfffffc84, 0xfffffc07, _not_used_, _not_used_, + _not_used_, _not_used_, _not_used_, _not_used_, + + /* exception. (offset 3c in upm RAM) */ + 0x7ffffc07, _not_used_, _not_used_, _not_used_ }; + +/* ------------------------------------------------------------------------- */ +#else +#error SDRAM not correctly configured +#endif + +int _initsdram(uint base, uint noMbytes) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + + if(noMbytes != 4) + { + return -1; + } + + upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint)); + + memctl->memc_mptpr = SDRAM_MPTPRVALUE; + + /* Configure the refresh (mostly). This needs to be + * based upon processor clock speed and optimized to provide + * the highest level of performance. For multiple banks, + * this time has to be divided by the number of banks. + * Although it is not clear anywhere, it appears the + * refresh steps through the chip selects for this UPM + * on each refresh cycle. + * We have to be careful changing + * UPM registers after we ask it to run these commands. + */ + + memctl->memc_mbmr = SDRAM_MBMRVALUE0; + memctl->memc_mar = SDRAM_MARVALUE; /* MRS code */ + + udelay(200); + + /* Now run the precharge/nop/mrs commands. + */ + + memctl->memc_mcr = 0x80808111; /* run pattern 0x11 */ + + udelay(200); + + /* Run 8 refresh cycles */ + + memctl->memc_mcr = SDRAM_MCRVALUE0; + + udelay(200); + + memctl->memc_mbmr = SDRAM_MBMRVALUE1; + memctl->memc_mcr = SDRAM_MCRVALUE1; + + udelay(200); + + memctl->memc_mbmr = SDRAM_MBMRVALUE0; + + memctl->memc_or4 = SDRAM_OR4VALUE; + memctl->memc_br4 = SDRAM_BR4VALUE | base; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +void _sdramdisable(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + + memctl->memc_br4 = 0x00000000; + + /* maybe we should turn off upmb here or something */ +} + +/* ------------------------------------------------------------------------- */ + +int initsdram(uint base, uint *noMbytes) +{ + uint m = 4; + + *((uint *)BCSR1) |= BCSR1_SDRAM_EN; /* enable sdram */ + /* _fads_sdraminit needs access to sdram */ + *noMbytes = m; + + if(!_initsdram(base, m)) + { + + return 0; + } + else + { + *((uint *)BCSR1) &= ~BCSR1_SDRAM_EN; /* disable sdram */ + + _sdramdisable(); + + return -1; + } +} + +long int initdram (int board_type) +{ +#ifdef CONFIG_ADS + /* ADS: has no SDRAM, so start DRAM at 0 */ + uint base = (unsigned long)0x0; +#else + /* FADS: has 4MB SDRAM, put DRAM above it */ + uint base = (unsigned long)0x00400000; +#endif + uint k, m, s; + + k = (*((uint *)BCSR2) >> 23) & 0x0f; + + m = 0; + + switch(k & 0x3) + { + /* "MCM36100 / MT8D132X" */ + case 0x00 : + m = 4; + break; + + /* "MCM36800 / MT16D832X" */ + case 0x01 : + m = 32; + break; + /* "MCM36400 / MT8D432X" */ + case 0x02 : + m = 16; + break; + /* "MCM36200 / MT16D832X ?" */ + case 0x03 : + m = 8; + break; + + } + + switch(k >> 2) + { + case 0x02 : + k = 70; + break; + + case 0x03 : + k = 60; + break; + + default : + printf("unknown dramdelay (0x%x) - defaulting to 70 ns", k); + k = 70; + } + +#ifdef CONFIG_FADS + /* the FADS is missing this bit, all rams treated as non-edo */ + s = 0; +#else + s = (*((uint *)BCSR2) >> 27) & 0x01; +#endif + + if(!_draminit(base, m, s, k)) + { +#ifdef CONFIG_FADS + uint sdramsz; +#endif + *((uint *)BCSR1) &= ~BCSR1_DRAM_EN; /* enable dram */ + +#ifdef CONFIG_FADS + if (!initsdram(0x00000000, &sdramsz)) { + m += sdramsz; + printf("(%u MB SDRAM) ", sdramsz); + } else { + _dramdisable(); + + /******************************** + *DRAM ERROR, HALT PROCESSOR + *********************************/ + while(1); + + return -1; + } +#endif + + return (m << 20); + } + else + { + _dramdisable(); + + /******************************** + *DRAM ERROR, HALT PROCESSOR + *********************************/ + while(1); + + return -1; + } +} + +/* ------------------------------------------------------------------------- */ + +int testdram (void) +{ + /* TODO: XXX XXX XXX */ + printf ("test: 16 MB - ok\n"); + + return (0); +} + + +#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) + +#ifdef CFG_PCMCIA_MEM_ADDR +volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR; +#endif + +int pcmcia_init(void) +{ + volatile pcmconf8xx_t *pcmp; + uint v, slota, slotb; + + /* + ** Enable the PCMCIA for a Flash card. + */ + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); + +#if 0 + pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR; + pcmp->pcmc_por0 = 0xc00ff05d; +#endif + + /* Set all slots to zero by default. */ + pcmp->pcmc_pgcra = 0; + pcmp->pcmc_pgcrb = 0; +#ifdef PCMCIA_SLOT_A + pcmp->pcmc_pgcra = 0x40; +#endif +#ifdef PCMCIA_SLOT_B + pcmp->pcmc_pgcrb = 0x40; +#endif + + /* enable PCMCIA buffers */ + *((uint *)BCSR1) &= ~BCSR1_PCCEN; + + /* Check if any PCMCIA card is plugged in. */ + + slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ; + slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ; + + if (!(slota || slotb)) + { + printf("No card present\n"); +#ifdef PCMCIA_SLOT_A + pcmp->pcmc_pgcra = 0; +#endif +#ifdef PCMCIA_SLOT_B + pcmp->pcmc_pgcrb = 0; +#endif + return -1; + } + else + printf("Card present ("); + + v = 0; + + /* both the ADS and the FADS have a 5V keyed pcmcia connector (?) + ** + ** Paolo - Yes, but i have to insert some 3.3V card in that slot on + ** my FADS... :-) + */ + +#if defined(CONFIG_MPC860) + switch( (pcmp->pcmc_pipr >> 30) & 3 ) +#elif defined(CONFIG_MPC823) || defined(CONFIG_MPC850) + switch( (pcmp->pcmc_pipr >> 14) & 3 ) +#endif + { + case 0x00 : + printf("5V"); + v = 5; + break; + case 0x01 : + printf("5V and 3V"); +#ifdef CONFIG_FADS + v = 3; /* User lower voltage if supported! */ +#else + v = 5; +#endif + break; + case 0x03 : + printf("5V, 3V and x.xV"); +#ifdef CONFIG_FADS + v = 3; /* User lower voltage if supported! */ +#else + v = 5; +#endif + break; + } + + switch(v){ +#ifdef CONFIG_FADS + case 3: + printf("; using 3V"); + /* + ** Enable 3 volt Vcc. + */ + *((uint *)BCSR1) &= ~BCSR1_PCCVCC1; + *((uint *)BCSR1) |= BCSR1_PCCVCC0; + break; +#endif + case 5: + printf("; using 5V"); +#ifdef CONFIG_ADS + /* + ** Enable 5 volt Vcc. + */ + *((uint *)BCSR1) &= ~BCSR1_PCCVCCON; +#endif +#ifdef CONFIG_FADS + /* + ** Enable 5 volt Vcc. + */ + *((uint *)BCSR1) &= ~BCSR1_PCCVCC0; + *((uint *)BCSR1) |= BCSR1_PCCVCC1; +#endif + break; + + default: + *((uint *)BCSR1) |= BCSR1_PCCEN; /* disable pcmcia */ + + printf("; unknown voltage"); + return -1; + } + printf(")\n"); + /* disable pcmcia reset after a while */ + + udelay(20); + +#ifdef MPC860 + pcmp->pcmc_pgcra = 0; +#elif MPC823 + pcmp->pcmc_pgcrb = 0; +#endif + + /* If you using a real hd you should give a short + * spin-up time. */ +#ifdef CONFIG_DISK_SPINUP_TIME + udelay(CONFIG_DISK_SPINUP_TIME); +#endif + + return 0; +} + +#endif /* CFG_CMD_PCMCIA */ + +/* ------------------------------------------------------------------------- */ + +#ifdef CFG_PC_IDE_RESET + +void ide_set_reset(int on) +{ + volatile immap_t *immr = (immap_t *)CFG_IMMR; + + /* + * Configure PC for IDE Reset Pin + */ + if (on) { /* assert RESET */ + immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET); + } else { /* release RESET */ + immr->im_ioport.iop_pcdat |= CFG_PC_IDE_RESET; + } + + /* program port pin as GPIO output */ + immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET); + immr->im_ioport.iop_pcso &= ~(CFG_PC_IDE_RESET); + immr->im_ioport.iop_pcdir |= CFG_PC_IDE_RESET; +} + +#endif /* CFG_PC_IDE_RESET */ +/* ------------------------------------------------------------------------- */ diff --git a/board/genietv/genietv.c b/board/genietv/genietv.c new file mode 100644 index 0000000..8f32ad7 --- /dev/null +++ b/board/genietv/genietv.c @@ -0,0 +1,375 @@ +/* + * genietv/genietv.c + * + * The GENIETV is using the following physical memorymap (copied from + * the FADS configuration): + * + * ff020000 -> ff02ffff : pcmcia + * ff010000 -> ff01ffff : BCSR connected to CS1, setup by 8xxROM + * ff000000 -> ff00ffff : IMAP internal in the cpu + * 02800000 -> 0287ffff : flash connected to CS0 + * 00000000 -> nnnnnnnn : sdram setup by U-Boot + * + * CS pins are connected as follows: + * + * CS0 -512Kb boot flash + * CS1 - SDRAM #1 + * CS2 - SDRAM #2 + * CS3 - Flash #1 + * CS4 - Flash #2 + * CS5 - LON (if present) + * CS6 - PCMCIA #1 + * CS7 - PCMCIA #2 + * + * Ports are configured as follows: + * + * PA7 - SDRAM banks enable + */ + +#include <common.h> +#include <mpc8xx.h> + +#define CFG_PA7 0x0100 + +/* ------------------------------------------------------------------------- */ + +static long int dram_size (long int, long int *, long int); + +/* ------------------------------------------------------------------------- */ + +#define _NOT_USED_ 0xFFFFFFFF + +const uint sdram_table[] = +{ + /* + * Single Read. (Offset 0 in UPMB RAM) + */ + 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBEEC00, + 0x1FFDDC47, /* last */ + /* + * SDRAM Initialization (offset 5 in UPMB RAM) + * + * This is no UPM entry point. The following definition uses + * the remaining space to establish an initialization + * sequence, which is executed by a RUN command. + * + */ + 0x1FFDDC34, 0xEFEEAC34, 0x1FBD5C35, /* last */ + /* + * Burst Read. (Offset 8 in UPMB RAM) + */ + 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00, + 0xF0AFFC00, 0xF1AFFC00, 0xEFBEEC00, 0x1FFDDC47, /* last */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Single Write. (Offset 18 in UPMB RAM) + */ + 0x1F2DFC04, 0xEEAFAC00, 0x01BE4C04, 0x1FFDDC47, /* last */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Burst Write. (Offset 20 in UPMB RAM) + */ + 0x1F0DFC04, 0xEEAFAC00, 0x10AF5C00, 0xF0AFFC00, + 0xF0AFFC00, 0xE1BEEC04, 0x1FFDDC47, /* last */ + _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Refresh (Offset 30 in UPMB RAM) + */ + 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, + 0xFFFFFC84, 0xFFFFFC07, /* last */ + _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Exception. (Offset 3c in UPMB RAM) + */ + 0x7FFFFC07, /* last */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, +}; + +/* ------------------------------------------------------------------------- */ + + +/* + * Check Board Identity + */ + +int checkboard (void) +{ + puts ("Board: GenieTV\n"); + return 0; +} + +#if 0 +static void PrintState(void) +{ + volatile immap_t *im = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &im->im_memctl; + + printf("\n0 - FLASH: B=%08x O=%08x", memctl->memc_br0, memctl->memc_or0); + printf("\n1 - SDRAM: B=%08x O=%08x", memctl->memc_br1, memctl->memc_or1); + printf("\n2 - SDRAM: B=%08x O=%08x", memctl->memc_br2, memctl->memc_or2); +} +#endif + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + volatile immap_t *im = (immap_t *)CFG_IMMR; + volatile memctl8xx_t *memctl = &im->im_memctl; + long int size_b0, size_b1, size8; + + /* Enable SDRAM */ + + /* Configuring PA7 for general purpouse output pin */ + im->im_ioport.iop_papar &= ~CFG_PA7 ; /* 0 = general purpouse */ + im->im_ioport.iop_padir |= CFG_PA7 ; /* 1 = output */ + + /* Enable SDRAM - PA7 = 1 */ + im->im_ioport.iop_padat |= CFG_PA7 ; /* value of PA7 */ + + /* + * Preliminary prescaler for refresh (depends on number of + * banks): This value is selected for four cycles every 62.4 us + * with two SDRAM banks or four cycles every 31.2 us with one + * bank. It will be adjusted after memory sizing. + */ + memctl->memc_mptpr = CFG_MPTPR_2BK_4K ; + + memctl->memc_mbmr = CFG_MBMR_8COL; + + upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint)); + + /* + * Map controller banks 1 and 2 to the SDRAM banks 1 and 2 at + * preliminary addresses - these have to be modified after the + * SDRAM size has been determined. + */ + + memctl->memc_or1 = 0xF0000000 | CFG_OR_TIMING_SDRAM; + memctl->memc_br1 = ((SDRAM_BASE1_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V); + + memctl->memc_or2 = 0xF0000000 | CFG_OR_TIMING_SDRAM; + memctl->memc_br2 = ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V); + + /* perform SDRAM initialization sequence */ + memctl->memc_mar = 0x00000088; + + memctl->memc_mcr = 0x80802105; /* SDRAM bank 0 */ + + memctl->memc_mcr = 0x80804105; /* SDRAM bank 1 */ + + /* Execute refresh 8 times */ + memctl->memc_mbmr = (CFG_MBMR_8COL & ~MAMR_TLFB_MSK) | MAMR_TLFB_8X ; + + memctl->memc_mcr = 0x80802130; /* SDRAM bank 0 - execute twice */ + + memctl->memc_mcr = 0x80804130; /* SDRAM bank 1 - execute twice */ + + /* Execute refresh 4 times */ + memctl->memc_mbmr = CFG_MBMR_8COL; + + /* + * Check Bank 0 Memory Size for re-configuration + * + * try 8 column mode + */ + +#if 0 + PrintState(); +#endif +/* printf ("\nChecking bank1..."); */ + size8 = dram_size (CFG_MBMR_8COL, (ulong *)SDRAM_BASE1_PRELIM, SDRAM_MAX_SIZE); + + size_b0 = size8 ; + +/* printf ("\nChecking bank2..."); */ + size_b1 = dram_size (memctl->memc_mbmr, (ulong *)SDRAM_BASE2_PRELIM,SDRAM_MAX_SIZE); + + /* + * Final mapping: map bigger bank first + */ + + memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; + memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V; + + if (size_b1 > 0) + { + /* + * Position Bank 1 immediately above Bank 0 + */ + memctl->memc_or2 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; + memctl->memc_br2 = ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V) + + (size_b0 & BR_BA_MSK); + } + else + { + /* + * No bank 1 + * + * invalidate bank + */ + memctl->memc_br2 = 0; + /* adjust refresh rate depending on SDRAM type, one bank */ + memctl->memc_mptpr = CFG_MPTPR_1BK_4K; + } + + /* If no memory detected, disable SDRAM */ + if ((size_b0 + size_b1) == 0) + { + printf("disabling SDRAM!\n"); + /* Disable SDRAM - PA7 = 1 */ + im->im_ioport.iop_padat &= ~CFG_PA7 ; /* value of PA7 */ + } +/* else */ +/* printf("done! (%08lx)\n", size_b0 + size_b1); */ + +#if 0 + PrintState(); +#endif + return (size_b0 + size_b1); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check memory range for valid RAM. A simple memory test determines + * the actually available RAM size between addresses `base' and + * `base + maxsize'. Some (not all) hardware errors are detected: + * - short between address lines + * - short between data lines + */ + +static long int dram_size (long int mbmr_value, long int *base, long int maxsize) +{ + volatile long int *addr; + long int cnt, val; + + /*memctl->memc_mbmr = mbmr_value; */ + + for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) { + addr = base + cnt; /* pointer arith! */ + + *addr = ~cnt; + } + + /* write 0 to base address */ + addr = base; + *addr = 0; + + /* check at base address */ + if ((val = *addr) != 0) { + printf("(0)"); + return (0); + } + + for (cnt = 1; ; cnt <<= 1) { + addr = base + cnt; /* pointer arith! */ + + val = *addr; + if (val != (~cnt)) { +/* printf("(%08lx)", cnt*sizeof(long)); */ + return (cnt * sizeof(long)); + } + } + /* NOTREACHED */ + return (0); +} + +#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) + +#ifdef CFG_PCMCIA_MEM_ADDR +volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR; +#endif + +int pcmcia_init(void) +{ + volatile pcmconf8xx_t *pcmp; + uint v, slota, slotb; + + /* + ** Enable the PCMCIA for a Flash card. + */ + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); + +#if 0 + pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR; + pcmp->pcmc_por0 = 0xc00ff05d; +#endif + + /* Set all slots to zero by default. */ + pcmp->pcmc_pgcra = 0; + pcmp->pcmc_pgcrb = 0; +#ifdef PCMCIA_SLOT_A + pcmp->pcmc_pgcra = 0x40; +#endif +#ifdef PCMCIA_SLOT_B + pcmp->pcmc_pgcrb = 0x40; +#endif + + /* Check if any PCMCIA card is luged in. */ + slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ; + slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ; + + if (!(slota || slotb)) + { + printf("No card present\n"); +#ifdef PCMCIA_SLOT_A + pcmp->pcmc_pgcra = 0; +#endif +#ifdef PCMCIA_SLOT_B + pcmp->pcmc_pgcrb = 0; +#endif + return -1; + } + else + printf("Unknown card ("); + + v = 0; + + switch( (pcmp->pcmc_pipr >> 14) & 3 ) + { + case 0x00 : + printf("5V"); + v = 5; + break; + case 0x01 : + printf("5V and 3V"); + v = 3; + break; + case 0x03 : + printf("5V, 3V and x.xV"); + v = 3; + break; + } + + switch(v){ + case 3: + printf("; using 3V"); + /* Enable 3 volt Vcc. */ + + break; + + default: + printf("; unknown voltage"); + return -1; + } + printf(")\n"); + /* disable pcmcia reset after a while */ + + udelay(20); + + pcmp->pcmc_pgcrb = 0; + + /* If you using a real hd you should give a short + * spin-up time. */ +#ifdef CONFIG_DISK_SPINUP_TIME + udelay(CONFIG_DISK_SPINUP_TIME); +#endif + + return 0; +} +#endif /* CFG_CMD_PCMCIA */ diff --git a/board/lart/config.mk b/board/lart/config.mk new file mode 100644 index 0000000..8f1a62b --- /dev/null +++ b/board/lart/config.mk @@ -0,0 +1,23 @@ +# +# LART board with SA1100 cpu +# +# see http://www.lart.tudelft.nl/ for more information on LART +# + +# +# LART has 4 banks of 8 MB DRAM +# +# c000'0000 +# c100'0000 +# c800'0000 +# c900'0000 +# +# Linux-Kernel is expected to be at c000'8000, entry c000'8000 +# +# we load ourself to c170'0000, the upper 1 MB of second bank +# +# download areas is c800'0000 +# + + +TEXT_BASE = 0xc1700000 diff --git a/board/lart/memsetup.S b/board/lart/memsetup.S new file mode 100644 index 0000000..bebd697 --- /dev/null +++ b/board/lart/memsetup.S @@ -0,0 +1,96 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* some parameters for the board */ + +MEM_BASE: .long 0xa0000000 +MEM_START: .long 0xc0000000 + +#define MDCNFG 0x00 +#define MDCAS0 0x04 +#define MDCAS1 0x08 +#define MDCAS2 0x0c +#define MSC0 0x10 +#define MSC1 0x14 +#define MECR 0x18 + +mdcas0: .long 0xc71c703f +mdcas1: .long 0xffc71c71 +mdcas2: .long 0xffffffff +/* mdcnfg: .long 0x0bb2bcbf */ +mdcnfg: .long 0x0334b22f @ alt +/* mcs0: .long 0xfff8fff8 */ +msc0: .long 0xad8c4888 @ alt +mecr: .long 0x00060006 +/* mecr: .long 0x994a994a @ alt */ + +/* setting up the memory */ + +.globl memsetup +memsetup: + ldr r0, MEM_BASE + + /* Setup the flash memory */ + ldr r1, msc0 + str r1, [r0, #MSC0] + + /* Set up the DRAM */ + + /* MDCAS0 */ + ldr r1, mdcas0 + str r1, [r0, #MDCAS0] + + /* MDCAS1 */ + ldr r1, mdcas1 + str r1, [r0, #MDCAS1] + + /* MDCAS2 */ + ldr r1, mdcas2 + str r1, [r0, #MDCAS2] + + /* MDCNFG */ + ldr r1, mdcnfg + str r1, [r0, #MDCNFG] + + /* Set up PCMCIA space */ + ldr r1, mecr + str r1, [r0, #MECR] + + /* Load something to activate bank */ + ldr r1, MEM_START + +.rept 8 + ldr r0, [r1] +.endr + + /* everything is fine now */ + mov pc, lr + diff --git a/board/lubbock/memsetup.S b/board/lubbock/memsetup.S new file mode 100644 index 0000000..c027834 --- /dev/null +++ b/board/lubbock/memsetup.S @@ -0,0 +1,749 @@ +/* + * Most of this taken from Redboot hal_platform_setup.h with cleanup + * + * NOTE: I haven't clean this up considerably, just enough to get it + * running. See hal_platform_setup.h for the source. See + * board/cradle/memsetup.S for another PXA250 setup that is + * much cleaner. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <version.h> +#include <asm/arch/pxa-regs.h> + +DRAM_SIZE: .long CFG_DRAM_SIZE + +/* wait for coprocessor write complete */ + .macro CPWAIT reg + mrc p15,0,\reg,c2,c0,0 + mov \reg,\reg + sub pc,pc,#4 + .endm + + +.globl memsetup +memsetup: + + mov r10, lr + + /* Set up GPIO pins first */ + + ldr r0, =GPSR0 + ldr r1, =CFG_GPSR0_VAL + str r1, [r0] + + ldr r0, =GPSR1 + ldr r1, =CFG_GPSR1_VAL + str r1, [r0] + + ldr r0, =GPSR2 + ldr r1, =CFG_GPSR2_VAL + str r1, [r0] + + ldr r0, =GPCR0 + ldr r1, =CFG_GPCR0_VAL + str r1, [r0] + + ldr r0, =GPCR1 + ldr r1, =CFG_GPCR1_VAL + str r1, [r0] + + ldr r0, =GPCR2 + ldr r1, =CFG_GPCR2_VAL + str r1, [r0] + + ldr r0, =GPDR0 + ldr r1, =CFG_GPDR0_VAL + str r1, [r0] + + ldr r0, =GPDR1 + ldr r1, =CFG_GPDR1_VAL + str r1, [r0] + + ldr r0, =GPDR2 + ldr r1, =CFG_GPDR2_VAL + str r1, [r0] + + ldr r0, =GAFR0_L + ldr r1, =CFG_GAFR0_L_VAL + str r1, [r0] + + ldr r0, =GAFR0_U + ldr r1, =CFG_GAFR0_U_VAL + str r1, [r0] + + ldr r0, =GAFR1_L + ldr r1, =CFG_GAFR1_L_VAL + str r1, [r0] + + ldr r0, =GAFR1_U + ldr r1, =CFG_GAFR1_U_VAL + str r1, [r0] + + ldr r0, =GAFR2_L + ldr r1, =CFG_GAFR2_L_VAL + str r1, [r0] + + ldr r0, =GAFR2_U + ldr r1, =CFG_GAFR2_U_VAL + str r1, [r0] + + /* enable GPIO pins */ + ldr r0, =PSSR + ldr r1, =CFG_PSSR_VAL + str r1, [r0] + + ldr r3, =MSC1 /* low - bank 2 Lubbock Registers / SRAM */ + ldr r2, =CFG_MSC1_VAL /* high - bank 3 Ethernet Controller */ + str r2, [r3] /* need to set MSC1 before trying to write to the HEX LEDs */ + ldr r2, [r3] /* need to read it back to make sure the value latches (see MSC section of manual) */ + + ldr r1, =LED_BLANK + mov r0, #0xFF + str r0, [r1] /* turn on hex leds */ + +loop: + ldr r0, =0xB0070001 + ldr r1, =_LED + str r0, [r1] /* hex display */ + +/********************************************************************* + Initlialize Memory Controller + The sequence below is based on the recommended init steps detailed + in the EAS, chapter 5 (Chapter 10, Operating Systems Developers Guide) + + + pause for 200 uSecs- allow internal clocks to settle + *Note: only need this if hard reset... doing it anyway for now +*/ + + @ ---- Wait 200 usec + ldr r3, =OSCR @ reset the OS Timer Count to zero + mov r2, #0 + str r2, [r3] + ldr r4, =0x300 @ really 0x2E1 is about 200usec, so 0x300 should be plenty +1: + ldr r2, [r3] + cmp r4, r2 + bgt 1b + +mem_init: + @ get memory controller base address + ldr r1, =MEMC_BASE + +@**************************************************************************** +@ Step 1 +@ + + @ write msc0, read back to ensure data latches + @ + ldr r2, =CFG_MSC0_VAL + str r2, [r1, #MSC0_OFFSET] + ldr r2, [r1, #MSC0_OFFSET] + + @ write msc1 + ldr r2, =CFG_MSC1_VAL + str r2, [r1, #MSC1_OFFSET] + ldr r2, [r1, #MSC1_OFFSET] + + @ write msc2 + ldr r2, =CFG_MSC2_VAL + str r2, [r1, #MSC2_OFFSET] + ldr r2, [r1, #MSC2_OFFSET] + + @ write mecr + ldr r2, =CFG_MECR_VAL + str r2, [r1, #MECR_OFFSET] + + @ write mcmem0 + ldr r2, =CFG_MCMEM0_VAL + str r2, [r1, #MCMEM0_OFFSET] + + @ write mcmem1 + ldr r2, =CFG_MCMEM1_VAL + str r2, [r1, #MCMEM1_OFFSET] + + @ write mcatt0 + ldr r2, =CFG_MCATT0_VAL + str r2, [r1, #MCATT0_OFFSET] + + @ write mcatt1 + ldr r2, =CFG_MCATT1_VAL + str r2, [r1, #MCATT1_OFFSET] + + @ write mcio0 + ldr r2, =CFG_MCIO0_VAL + str r2, [r1, #MCIO0_OFFSET] + + @ write mcio1 + ldr r2, =CFG_MCIO1_VAL + str r2, [r1, #MCIO1_OFFSET] + + @------------------------------------------------------- + @ 3rd bullet, Step 1 + @ + + @ get the mdrefr settings + ldr r3, =CFG_MDREFR_VAL_100 + + @ extract DRI field (we need a valid DRI field) + @ + ldr r2, =0xFFF + + @ valid DRI field in r3 + @ + and r3, r3, r2 + + @ get the reset state of MDREFR + @ + ldr r4, [r1, #MDREFR_OFFSET] + + @ clear the DRI field + @ + bic r4, r4, r2 + + @ insert the valid DRI field loaded above + @ + orr r4, r4, r3 + + @ write back mdrefr + @ + str r4, [r1, #MDREFR_OFFSET] + + @ *Note: preserve the mdrefr value in r4 * + +@**************************************************************************** +@ Step 2 +@ + /* This should be for SRAM, why is it commented out??? */ + + @ fetch sxcnfg value + @ + @ldr r2, =0 + @ write back sxcnfg + @str r2, [r1, #SXCNFG_OFFSET] + +/* @if sxcnfg=0, don't program for synch-static memory */ + @cmp r2, #0 + @beq 1f + + @program sxmrs + @ldr r2, =SXMRS_SETTINGS + @str r2, [r1, #SXMRS_OFFSET] + + +@**************************************************************************** +@ Step 3 +@ + + @ Assumes previous mdrefr value in r4, if not then read current mdrefr + + @ clear the free-running clock bits + @ (clear K0Free, K1Free, K2Free + @ + bic r4, r4, #(0x00800000 | 0x01000000 | 0x02000000) + + @ set K1RUN if bank 0 installed + @ + orr r4, r4, #0x00010000 + + + +#ifdef THIS +@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!< +@<!<!<!<!<!<!<!<!<!<!<! Begin INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!< + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @ Lubbock: Allow the user to select the {T/R/M} with predetermined + @ SDCLK. Based on Table 3-1 in PXA250 and PXA210 Dev Man. + @ + @ * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1] + @ + @ S25, S26 used to provide all 400 MHz BIN values for Cotulla (0,0 - 1,3) + @ S25, S26 used to provide all 200 MHz BIN values for Sabinal + @ + @ S23: Force the halving of MemClk when deriving SDCLK[1] + @ DOT: no override !DOT: halve (if not already forced half) +/* @ *For certain MemClks, SDCLK's derivation is forced to be halved */ + @ + @ S24: Run/Turbo. + @ DOT: Run mode !DOT: Turbo mode + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + @ + @ Allow the user to control K1DB2 where applicable + @ + @ Get the value of S23: @ 1 = DOT (unity), 0 = !DOT (halve it) + @ + @ DOT: set K1DB2 (SDCLD = MemClk) + @ !DOT: clear K1DB2 (SDCLK = MemClk/2) + @ + @ldr r2, =FPGA_REGS_BASE_PHYSICAL + + bl GET_S23 @ r3, r2 @ get the value of S23 in R0, i put the base adx of fpga in r3 + + cmp r3, #0x0 @ is !DOT? + orreq r4, r4, #0x00020000 @ SDClk[1] = MemClk/2 + bicne r4, r4, #0x00020000 @ SDClk[1] = MemClk + + @ + @ Next, we need to look for S25,S26 selections that necessitate the + @ halving of MemClk to derive SDCLK[1]: (S25,S26)={03-0C, 10-13} + @ Override above S23-based selection accordingly. + @ + ldr r2, =FPGA_REGS_BASE_PHYSICAL + bl GET_S25 @ r0, r2 + @ get the value of S25 in R0, i put the base adx of fpga in r2 + + + + ldr r2, =FPGA_REGS_BASE_PHYSICAL + BL GET_S26 @ r3, r2 + @ get the value of S26 in R1, i put the base adx of fpga in r2 + + orr r0, r0, r3 @ concatenate S25 & S26 vals + and r0, r0, #0xFF + + @ Set K1DB2 for the frequencies that require it + @ + cmp r0, #0x03 + cmpne r0, #0x04 + cmpne r0, #0x05 + cmpne r0, #0x06 + cmpne r0, #0x07 + cmpne r0, #0x08 + cmpne r0, #0x09 + cmpne r0, #0x0A + cmpne r0, #0x0B + cmpne r0, #0x0C + cmpne r0, #0x10 + cmpne r0, #0x11 + cmpne r0, #0x12 + cmpne r0, #0x13 + orreq r4, r4, #0x00020000 @ SDCLK[1] = (MemClk)/2 for 03 - 0C @ 10 - 13 + + @ + @ *Must make MSC0&1 adjustments now for MEMClks > 100MHz. + @ + @ Adjust MSC0 for MemClks > 100 MHz + @ + ldreq r0, [r1, #MSC0_OFFSET] + ldreq r3, =0x7F007F00 + biceq r0, r0, r3 @ clear MSC0[14:12, 11:8] (RRR, RDN) + ldreq r3, =0x46004600 + orreq r0, r0, r3 @ set MSC0[14, 10:9] (doubling RRR, RDN) + streq r0, [r1, #MSC0_OFFSET] + ldreq r0, [r1, #MSC0_OFFSET] @ read it back to ensure that the data latches + + @ + @ Adjust MSC1.LH for MemClks > 100 MHz + @ + ldreq r0, [r1, #MSC1_OFFSET] + ldreq r3, =0x7FF0 + biceq r0, r0, r3 @ clear MSC1[14:12, 11:8, 7:4] (RRR, RDN, RDF) + ldreq r3, =0x4880 + orreq r0, r0, r3 @ set MSC1[14, 11, 7] (doubling RRR, RDN, RDF) + streq r0, [r1, #MSC1_OFFSET] + ldreq r0, [r1, #MSC1_OFFSET] @ read it back to ensure that the data latches + + @ @ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif + +@<!<!<!<!<!<!<!<!<!<!<! End INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!< +@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!< + + + @ write back mdrefr + @ + str r4, [r1, #MDREFR_OFFSET] + ldr r4, [r1, #MDREFR_OFFSET] + + @ deassert SLFRSH + @ + bic r4, r4, #0x00400000 + + @ write back mdrefr + @ + str r4, [r1, #MDREFR_OFFSET] + + @ assert E1PIN + @ + orr r4, r4, #0x00008000 + + @ write back mdrefr + @ + str r4, [r1, #MDREFR_OFFSET] + ldr r4, [r1, #MDREFR_OFFSET] + nop + nop + + +@**************************************************************************** +@ Step 4 +@ + + @ fetch platform value of mdcnfg + @ + ldr r2, =CFG_MDCNFG_VAL + + @ disable all sdram banks + @ + bic r2, r2, #(MDCNFG_DE0 | MDCNFG_DE1) + bic r2, r2, #(MDCNFG_DE2 | MDCNFG_DE3) + + @ program banks 0/1 for bus width + @ + bic r2, r2, #MDCNFG_DWID0 @0=32-bit + + + @ write initial value of mdcnfg, w/o enabling sdram banks + @ + str r2, [r1, #MDCNFG_OFFSET] + +@ **************************************************************************** +@ Step 5 +@ + + @ pause for 200 uSecs + @ + ldr r3, =OSCR @reset the OS Timer Count to zero + mov r2, #0 + str r2, [r3] + ldr r4, =0x300 @really 0x2E1 is about 200usec, so 0x300 should be plenty +1: + ldr r2, [r3] + cmp r4, r2 + bgt 1b + + +@**************************************************************************** +@ Step 6 +@ + + mov r0, #0x78 @turn everything off + mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.) + + +@ **************************************************************************** +@ Step 7 +@ + @ Access memory *not yet enabled* for CBR refresh cycles (8) + @ - CBR is generated for all banks + + ldr r2, =CFG_DRAM_BASE + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + + +@ **************************************************************************** +@ Step 8: NOP (enable dcache if you wanna... we dont) +@ + + +@ **************************************************************************** +@ Step 9 +@ + + + @get memory controller base address + @ + ldr r1, =MEMC_BASE + + @fetch current mdcnfg value + @ + ldr r3, [r1, #MDCNFG_OFFSET] + + @enable sdram bank 0 if installed (must do for any populated bank) + @ + orr r3, r3, #MDCNFG_DE0 + + @write back mdcnfg, enabling the sdram bank(s) + @ + str r3, [r1, #MDCNFG_OFFSET] + + +@**************************************************************************** +@ Step 10 +@ + + @ write mdmrs + @ + ldr r2, =CFG_MDMRS_VAL + str r2, [r1, #MDMRS_OFFSET] + + +@**************************************************************************** +@ Step 11: Final Step +@ + +@INITINTC + @******************************************************************** + @ Disable (mask) all interrupts at the interrupt controller + @ + + @ clear the interrupt level register (use IRQ, not FIQ) + @ + mov r1, #0 + ldr r2, =ICLR + str r1, [r2] + + @ mask all interrupts at the controller + @ + ldr r2, =ICMR + str r1, [r2] + + +@INITCLKS + @ ******************************************************************** + @ Disable the peripheral clocks, and set the core clock + @ frequency (hard-coding at 398.12MHz for now). + @ + + @ Turn Off ALL on-chip peripheral clocks for re-configuration + @ *Note: See label 'ENABLECLKS' for the re-enabling + @ + ldr r1, =CKEN + mov r2, #0 + str r2, [r1] + + + @ default value in case no valid rotary switch setting is found + ldr r2, =(CCCR_L27 | CCCR_M2 | CCCR_N10) @ DEFAULT: {200/200/100} + + + @... and write the core clock config register + @ + ldr r1, =CCCR + str r2, [r1] + +/* @ enable the 32Khz oscillator for RTC and PowerManager + @ + ldr r1, =OSCC + mov r2, #OSCC_OON + str r2, [r1] + + + @ NOTE: spin here until OSCC.OOK get set, + @ meaning the PLL has settled. + @ +60: + ldr r2, [r1] + ands r2, r2, #1 + beq 60b +*/ + +@OSCC_OON_DONE + + +#ifdef A0_COTULLA + @**************************************************************************** + @ !!! Take care of A0 Errata Sighting #4 -- + @ after a frequency change, the memory controller must be restarted + @ + + @ get memory controller base address + ldr r1, =MEMC_BASE + + @ get the current state of MDREFR + @ + ldr r2, [r1, #MDREFR_OFFSET] + + @ clear E0PIN, E1PIN + @ + bic r3, r2, #(MDREFR_E0PIN | MDREFR_E1PIN) + + @ write MDREFR with E0PIN, E1PIN cleared (disable sdclk[0,1]) + @ + str r3, [r1, #MDREFR_OFFSET] + + @ then write MDREFR with E0PIN, E1PIN set (enable sdclk[0,1]) + @ + str r2, [r1, #MDREFR_OFFSET] + + @ get the current state of MDCNFG + @ + ldr r3, [r1, #MDCNFG_OFFSET] + + @ disable all SDRAM banks + @ + bic r3, r3, #(MDCNFG_DE0 | MDCNFG_DE1) + bic r3, r3, #(MDCNFG_DE2 | MDCNFG_DE3) + + @ write back MDCNFG + @ + ldr r3, [r1, #MDCNFG_OFFSET] + + @ Access memory not yet enabled for CBR refresh cycles (8) + @ - CBR is generated for *all* banks + ldr r2, =CFG_DRAM_BASE + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + str r2, [r2] + + @ fetch current mdcnfg value + @ + ldr r3, [r1, #MDCNFG_OFFSET] + + @ enable sdram bank 0 if installed + @ + orr r3, r3, #MDCNFG_DE0 + + @ write back mdcnfg, enabling the sdram bank(s) + @ + str r3, [r1, #MDCNFG_OFFSET] + + @ write mdmrs + @ + ldr r2, =CFG_MDMRS_VAL + str r2, [r1, #MDMRS_OFFSET] + + + + /* @ errata: don't enable auto power-down */ + @ get current value of mdrefr + @ldr r3, [r1, #MDREFR_OFFSET] + @ enable auto-power down + @orr r3, r3, #MDREFR_APD + @write back mdrefr + @str r3, [r1, #MDREFR_OFFSET] + +#endif A0_Cotulla + + + ldr r0, =0x000C0dE3 + ldr r1, =_LED + str r0, [r1] /* hex display */ + +@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^% +@ ^%^%^%^%^%^%^%^%^% above could be replaced by prememLLI ^%^%^%^%^%^%^%^%^% +@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^% + + + /* Save SDRAM size */ + ldr r1, =DRAM_SIZE + str r8, [r1] + + ldr r0, =0xC0DE0006 + ldr r1, =_LED + str r0, [r1] /* hex display */ + + /* Interrupt init */ + /* Mask all interrupts */ + ldr r0, =ICMR /* enable no sources */ + mov r1, #0 + str r1, [r0] + +#define NODEBUG +#ifdef NODEBUG + /*Disable software and data breakpoints */ + mov r0,#0 + mcr p15,0,r0,c14,c8,0 /* ibcr0 */ + mcr p15,0,r0,c14,c9,0 /* ibcr1 */ + mcr p15,0,r0,c14,c4,0 /* dbcon */ + + /*Enable all debug functionality */ + mov r0,#0x80000000 + mcr p14,0,r0,c10,c0,0 /* dcsr */ + +#endif + + ldr r0, =0xBEEF001D + ldr r1, =_LED + str r0, [r1] /* hex display */ + + mov pc, r10 + +@ End memsetup + +@ %%%%%%%%%%% Useful subroutines +GET_S23: + @ This macro will read S23 and return its value in r3 + @ r2 contains the base address of the Lubbock user registers + ldr r2, =FPGA_REGS_BASE_PHYSICAL + + /*@ read S23's value */ + ldr r3, [r2, #USER_SWITCHES_OFFSET] + + @ mask out irrelevant bits + and r3, r3, #0x200 + + @ get bit into position 0 + mov r3, r3, LSR #9 + + mov pc, lr +@ End GET_S23 + + +GET_S24: + @ This macro will read S24 and return its value in r0 + @ r2 contains the base address of the Lubbock user registers + ldr r2, =FPGA_REGS_BASE_PHYSICAL + + /*@ read S24's value */ + ldr r0, [r2, #USER_SWITCHES_OFFSET] + + @ mask out irrelevant bits + and r0, r0, #0x100 + + @ get bit into position 0 + mov r0, r0, LSR #8 + + mov pc, lr +@ End GET_S23 + + +GET_S25: + @ This macro will read rotary S25 and return its value in r0 + @ r2 contains the base address of the Lubbock user registers + @ read the user switches register + ldr r0, [r2, #USER_SWITCHES_OFFSET] + + @ mask out irrelevant bits + and r0, r0, #0xF0 + + mov pc, lr +@ End subroutine + + +GET_S26: + @ This macro will read rotary S26 and return its value in r3 + @ r2 contains the base address of the Lubbock user registers + @ read the user switches register + ldr r3, [r2, #USER_SWITCHES_OFFSET] + + @ mask out irrelevant bits + and r3, r3, #0x0F + + mov pc, lr +@ End subroutine GET_S26 + + diff --git a/board/mbx8xx/config.mk b/board/mbx8xx/config.mk new file mode 100644 index 0000000..d5e8ed2 --- /dev/null +++ b/board/mbx8xx/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# MBX8xx boards +# + +TEXT_BASE = 0xfe000000 +/*TEXT_BASE = 0x00200000 */ diff --git a/board/ml2/flash.c b/board/ml2/flash.c new file mode 100644 index 0000000..77e0931 --- /dev/null +++ b/board/ml2/flash.c @@ -0,0 +1,301 @@ +/* + * flash.c: Support code for the flash chips on the Xilinx ML2 board + * + * Copyright 2002 Mind NV + * + * http://www.mind.be/ + * + * Author : Peter De Schrijver (p2@mind.be) + * + * This software may be used and distributed according to the terms of + * the GNU General Public License (GPL) version 2, incorporated herein by + * reference. Drivers based on or derived from this code fall under the GPL + * and must retain the authorship, copyright and this license notice. This + * file is not a complete program and may only be used when the entire program + * is licensed under the GPL. + * + */ + +#include <common.h> +#include <asm/u-boot.h> +#include <configs/ML2.h> + +#define FLASH_BANK_SIZE (64*1024*1024) + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +#define SECT_SIZE (512*1024) + +#define CMD_READ_ARRAY 0x00FF00FF00FF00FULL +#define CMD_IDENTIFY 0x0090009000900090ULL +#define CMD_ERASE_SETUP 0x0020002000200020ULL +#define CMD_ERASE_CONFIRM 0x00D000D000D000D0ULL +#define CMD_PROGRAM 0x0040004000400040ULL +#define CMD_RESUME 0x00D000D000D000D0ULL +#define CMD_SUSPEND 0x00B000B000B000B0ULL +#define CMD_STATUS_READ 0x0070007000700070ULL +#define CMD_STATUS_RESET 0x0050005000500050ULL + +#define BIT_BUSY 0x0080008000800080ULL +#define BIT_ERASE_SUSPEND 0x004000400400040ULL +#define BIT_ERASE_ERROR 0x0020002000200020ULL +#define BIT_PROGRAM_ERROR 0x0010001000100010ULL +#define BIT_VPP_RANGE_ERROR 0x0008000800080008ULL +#define BIT_PROGRAM_SUSPEND 0x0004000400040004ULL +#define BIT_PROTECT_ERROR 0x0002000200020002ULL +#define BIT_UNDEFINED 0x0001000100010001ULL + +#define BIT_SEQUENCE_ERROR 0x0030003000300030ULL + +#define BIT_TIMEOUT 0x80000000 + + +inline void eieio(void) { + + __asm__ __volatile__ ("eieio" : : : "memory"); + +} + +ulong flash_init(void) { + + int i, j; + ulong size = 0; + + for(i=0;i<CFG_MAX_FLASH_BANKS;i++) { + ulong flashbase = 0; + + flash_info[i].flash_id = (INTEL_MANUFACT & FLASH_VENDMASK) | + (INTEL_ID_28F128J3A & FLASH_TYPEMASK); + flash_info[i].size = FLASH_BANK_SIZE; + flash_info[i].sector_count = CFG_MAX_FLASH_SECT; + memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); + if (i==0) + flashbase = CFG_FLASH_BASE; + else + panic("configured to many flash banks!\n"); + for (j = 0; j < flash_info[i].sector_count; j++) + flash_info[i].start[j]=flashbase + j * SECT_SIZE; + + size += flash_info[i].size; + } + + return size; +} + +void flash_print_info (flash_info_t *info) { + + int i; + + switch (info->flash_id & FLASH_VENDMASK) { + case (INTEL_MANUFACT & FLASH_VENDMASK): + printf("Intel: "); + break; + default: + printf("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case (INTEL_ID_28F128J3A & FLASH_TYPEMASK): + printf("4x 28F128J3A (128Mbit)\n"); + break; + default: + printf("Unknown Chip Type\n"); + break; + } + + printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count); + printf(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; i++) { + if ((i % 5) == 0) + printf("\n "); + printf (" %08lX%s", info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); +} + +int flash_error (unsigned long long code) { + + if (code & BIT_TIMEOUT) { + printf ("Timeout\n"); + return ERR_TIMOUT; + } + + if (~code & BIT_BUSY) { + printf ("Busy\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_VPP_RANGE_ERROR) { + printf ("Vpp range error\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_PROTECT_ERROR) { + printf ("Device protect error\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_SEQUENCE_ERROR) { + printf ("Command seqence error\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_ERASE_ERROR) { + printf ("Block erase error\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_PROGRAM_ERROR) { + printf ("Program error\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_ERASE_SUSPEND) { + printf ("Block erase suspended\n"); + return ERR_PROG_ERROR; + } + + if (code & BIT_PROGRAM_SUSPEND) { + printf ("Program suspended\n"); + return ERR_PROG_ERROR; + } + + return ERR_OK; + +} + +int flash_erase (flash_info_t *info, int s_first, int s_last) { + + int rc = ERR_OK; + int sect; + unsigned long long result; + + if (info->flash_id == FLASH_UNKNOWN) + return ERR_UNKNOWN_FLASH_TYPE; + + if ((s_first < 0) || (s_first > s_last)) + return ERR_INVAL; + + if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) + return ERR_UNKNOWN_FLASH_VENDOR; + + for (sect=s_first; sect<=s_last; ++sect) + if (info->protect[sect]) + return ERR_PROTECTED; + + for (sect = s_first; sect<=s_last && !ctrlc(); sect++) { + volatile unsigned long long *addr= + (unsigned long long *)(info->start[sect]); + + printf("Erasing sector %2d ... ", sect); + + *addr=CMD_STATUS_RESET; + eieio(); + *addr=CMD_ERASE_SETUP; + eieio(); + *addr=CMD_ERASE_CONFIRM; + eieio(); + + do { + result = *addr; + } while(~result & BIT_BUSY); + + *addr=CMD_READ_ARRAY; + + if ((rc = flash_error(result)) == ERR_OK) + printf("ok.\n"); + else + break; + } + + if (ctrlc()) + printf("User Interrupt!\n"); + + return rc; +} + +volatile static int write_word (flash_info_t *info, ulong dest, unsigned long long data) { + + volatile unsigned long long *addr=(unsigned long long *)dest; + unsigned long long result; + int rc = ERR_OK; + + result=*addr; + if ((result & data) != data) + return ERR_NOT_ERASED; + + *addr=CMD_STATUS_RESET; + eieio(); + *addr=CMD_PROGRAM; + eieio(); + *addr=data; + eieio(); + + do { + result=*addr; + } while(~result & BIT_BUSY); + + *addr=CMD_READ_ARRAY; + + rc = flash_error(result); + + return rc; + +} + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) { + + ulong cp, wp; + unsigned long long data; + int l; + int i,rc; + + wp=(addr & ~7); + + if((l=addr-wp) != 0) { + data=0; + for(i=0,cp=wp;i<l;++i,++cp) + data = (data >> 8) | (*(uchar *)cp << 24); + + for (; i<8 && cnt>0; ++i) { + data = (data >> 8) | (*src++ << 24); + --cnt; + ++cp; + } + + for (; i<8; ++i, ++cp) + data = (data >> 8) | (*(uchar *)cp << 24); + + if ((rc = write_word(info, wp, data)) != 0) + return rc; + + wp+=8; + } + + while(cnt>=8) { + data=*((unsigned long long *)src); + if ((rc = write_word(info, wp, data)) != 0) + return rc; + src+=8; + wp+=8; + cnt-=8; + } + + if(cnt == 0) + return ERR_OK; + + data = 0; + for (i=0, cp=wp; i<8 && cnt>0; ++i, ++cp) { + data = (data >> 8) | (*src++ << 24); + --cnt; + } + for (; i<8; ++i, ++cp) { + data = (data >> 8) | (*(uchar *)cp << 24); + } + + return write_word(info, wp, data); + +} + diff --git a/board/ml2/init.S b/board/ml2/init.S new file mode 100644 index 0000000..2386c2a --- /dev/null +++ b/board/ml2/init.S @@ -0,0 +1,34 @@ +/* + * init.S: Stubs for U-Boot initialization + * + * Copyright 2002 Mind NV + * + * http://www.mind.be/ + * + * Author : Peter De Schrijver (p2@mind.be) + * + * This software may be used and distributed according to the terms of + * the GNU General Public License (GPL) version 2, incorporated herein by + * reference. Drivers based on or derived from this code fall under the GPL + * and must retain the authorship, copyright and this license notice. This + * file is not a complete program and may only be used when the entire + * program is licensed under the GPL. + * + */ + +#include <ppc4xx.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + + + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + blr + + .globl sdram_init +sdram_init: + blr diff --git a/board/ml2/ml2.c b/board/ml2/ml2.c new file mode 100644 index 0000000..a89a8f9 --- /dev/null +++ b/board/ml2/ml2.c @@ -0,0 +1,67 @@ +/* + * ml2.c: U-Boot platform support for Xilinx ML2 board + * + * Copyright 2002 Mind NV + * + * http://www.mind.be/ + * + * Author : Peter De Schrijver (p2@mind.be) + * + * Derived from : Other platform support files in this tree + * + * This software may be used and distributed according to the terms of + * the GNU General Public License (GPL) version 2, incorporated herein by + * reference. Drivers based on or derived from this code fall under the GPL + * and must retain the authorship, copyright and this license notice. This + * file is not a complete program and may only be used when the entire + * program is licensed under the GPL. + * + */ + +#include <common.h> +#include <asm/processor.h> + + + +int board_pre_init (void) +{ + return 0; +} + + +int checkboard (void) +{ + unsigned char *s = getenv ("serial#"); + unsigned char *e; + + if (!s || strncmp (s, "ML2", 9)) { + printf ("### No HW ID - assuming ML2"); + } else { + for (e = s; *e; ++e) { + if (*e == ' ') + break; + } + + for (; s < e; ++s) { + putc (*s); + } + } + + + putc ('\n'); + + return (0); +} + + +long int initdram (int board_type) +{ + return 32 * 1024 * 1024; +} + +int testdram (void) +{ + printf ("test: xxx MB - ok\n"); + + return (0); +} diff --git a/board/mousse/README b/board/mousse/README new file mode 100644 index 0000000..ef072bd --- /dev/null +++ b/board/mousse/README @@ -0,0 +1,350 @@ + +U-Boot for MOUSSE/MPC8240 (KAHLUA) +---------------------------------- +James Dougherty (jfd@broadcom.com), 09/10/01 + +The Broadcom/Vooha Mousse board is a 3U Compact PCI system board +which uses the MPC8240, a 64MB SDRAM SIMM, and has onboard +DEC 21143, NS16550 UART, an SGS M48T59Y TOD, and 4MB FLASH. +See also: http://www.vooha.com/ + +* NVRAM setenv/printenv/savenv supported. +* Date Command +* Serial Console support +* Network support +* FLASH of kernel images is supported. +* FLASH of U-Boot to onboard and PLCC boot region. +* Kernel command line options from NVRAM is supported. +* IP PNP options supported. + +U-Boot Loading... + + + +U-Boot 1.0.5 (Sep 10 2001 - 00:22:25) + +CPU: MPC8240 Revision 1.1 at 198 MHz: 16 kB I-Cache 16 kB D-Cache +Board: MOUSSE MPC8240/KAHLUA - CHRP (MAP B) +Built: Sep 10 2001 at 01:01:50 +MPLD: Revision 127 +Local Bus: 33 MHz +RTC: M48T589 TOD/NVRAM (8176) bytes + Current date/time: 9/10/2001 0:18:52 +DRAM: 64 MB +FLASH: 1.960 MB +PCI: scanning bus0 ... + bus dev fn venID devID class rev MBAR0 MBAR1 IPIN ILINE + 00 00 00 1057 0003 060000 11 00000008 00000000 01 00 + 00 0d 00 1011 0019 020000 41 80000001 80000000 01 01 + 00 0e 00 105a 4d38 018000 01 a0000001 a0001001 01 03 +In: serial +Out: serial +Err: serial + +Hit any key to stop autoboot: 0 +=> + +I. Root FileSystem/IP Configuration + +bootcmd=tftp 100000 vmlinux.img;bootm +bootdelay=3 +baudrate=9600 +ipaddr=<IP ADDRESS> +netmask=<NETMASK> +hostname=<NAME> +serverip=<NFS SERVER IP ADDRESS> +ethaddr=00:00:10:20:30:44 +nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs +gateway=<IP ADDRESS> +root=/dev/nfs +stdin=serial +stdout=serial +stderr=serial + +NVRAM environment variables. + +use the command: + +setenv <attribute> <value> + +type "saveenv" to write to NVRAM. + + + +II. To boot from a hard drive: + +setenv root /dev/hda1 + + +III. IP options which configure the network: + +ipaddr=<IP ADDRESS OF MACHINE> +netmask=<NETMASK> +hostname=mousse +ethaddr=00:00:10:20:30:44 +gateway=<IP ADDRESS OF GATEWAY/ROUTER> + + +IV. IP Options which configure NFS Root/Boot Support + +root=/dev/nfs +serverip=<NFS SERVER IP ADDRESS> +nfsroot=<NFS SERVER IP ADDRESS>:/boot/root-fs + +V. U-Boot Image Support + +The U-Boot boot loader assumes that after you build +your kernel (vmlinux), you will create a U-Boot image +using the following commands or script: + +#!/bin/csh +/bin/touch vmlinux.img +/bin/rm vmlinux.img +set path=($TOOLBASE/bin $path) +set path=($U_BOOT/tools $path) +powerpc-linux-objcopy -S -O binary vmlinux vmlinux.bin +gzip -vf vmlinux.bin +mkimage -A ppc -O linux -T kernel -C gzip -a 0 -e 0 -n vmlinux.bin.gz -d vmlinux.bin.gz vmlinux.img +ls -l vmlinux.img + + +VI. ONBOARD FLASH Support + +FLASH support is provided for the onboard FLASH chip Bootrom area. +U-Boot is loaded into either the ROM boot region of the FLASH chip, +after first being boot-strapped from a pre-progammed AMD29F040 PLCC +bootrom. The PLCC needs to be programmed with a ROM burner using +AMD 29F040 ROM parts and the u-boot.bin or u-boot.hex (S-Record) +images. + +The PLCC overlays this same region of flash as the onboard FLASH, +the jumper J100 is a chip-select for which flash chip you want to +progam. When jumper J100 is connected to pins 2-3, you boot from +PLCC FLASH. + +To bringup a system, simply flash a flash an AMD29F040 PLCC +bootrom, and put this in the PLCC socket. Move jumper J100 to +pins 2-3 and boot from the PLCC. + + +Now, while the system is running, move Jumper J100 to +pins 1-2 and follow the procedure below to FLASH a bootrom +(u-boot.bin) image into the onboard bootrom region (AMD29LV160DB): + +tftp 100000 u-boot.bin +protect off FFF00000 FFF7FFFF +erase FFF00000 FFF7FFFF +cp.b 100000 FFF00000 \$(filesize)\ + + +Here is an example: + +=>tftp 100000 u-boot.bin +eth_halt +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +Filename 'u-boot.bin'. +Load address: 0x100000 +Loading: ######################### +done +Bytes transferred = 123220 (1e154 hex) +eth_halt +=>protect off FFF00000 FFF7FFFF +Un-Protected 8 sectors +=>erase FFF00000 FFF7FFFF +Erase Flash from 0xfff00000 to 0xfff7ffff +Erase FLASH[PLCC_BOOT] -8 sectors:........ done +Erased 8 sectors +=>cp.b 100000 FFF00000 1e154 +Copy to Flash... FLASH[PLCC_BOOT]:..done +=> + + +B. FLASH RAMDISK REGION + +FLASH support is provided for an Onboard 512K RAMDISK region. + +TThe following commands will FLASH a bootrom (u-boot.bin) image +into the onboard FLASH region (AMD29LV160DB 2MB FLASH): + +tftp 100000 u-boot.bin +protect off FFF80000 FFFFFFFF +erase FFF80000 FFFFFFFF +cp.b 100000 FFF80000 \$(filesize)\ + + + +C. FLASH KERNEL REGION (960KB) + +FLASH support is provided for the 960KB onboard FLASH1 segment. +This allows flashing of kernel images which U-Boot can load +and run (standalone) from the onboard FLASH chip. It also assumes + +The following commands will FLASH a kernel image to 0xffe10000 + +tftp 100000 vmlinux.img +protect off FFE10000 FFEFFFFF +erase FFE10000 FFEFFFFF +cp.b 100000 FFE10000 \$(filesize)\ +reset + +Here is an example: + + +=>tftp 100000 vmlinux.img +eth_halt +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +TFTP from server 209.128.93.133; our IP address is 209.128.93.138 +Filename 'vmlinux.img'. +Load address: 0x100000 +Loading: ##################################################################################################################################################### +done +Bytes transferred = 760231 (b99a7 hex) +eth_halt +=>protect off FFE10000 FFEFFFFF +Un-Protected 15 sectors +=>erase FFE10000 FFEFFFFF +Erase Flash from 0xffe10000 to 0xffefffff +Erase FLASH[F0_SA3(KERNEL)] -15 sectors:............... done +Erased 15 sectors +=>cp.b 100000 FFE10000 b99a7 +Copy to Flash... FLASH[F0_SA3(KERNEL)]:............done +=> + + + +When finished, use the command: + +bootm ffe10000 + +to start the kernel. + +Finally, to make this the default boot command, use +the following commands: + +setenv bootcmd bootm ffe10000 +savenv + +to make it automatically boot the kernel from FLASH. + + +To go back to development mode (NFS boot) + +setenv bootcmd tftp 100000 vmlinux.img\;bootm +savenv + + +=>tftp 100000 vmlinux.img +eth0: DC21143 Ethernet adapter(bus=0, device=13, func=0) +DEC Ethernet iobase=0x80000000 +ARP broadcast 1 +Filename 'vmlinux.img'. +Load address: 0x100000 +Loading: #################################################################################################################################################### +done +Bytes transferred = 752717 (b7c4d hex) +eth_halt +=>protect off FFE10000 FFEFFFFF +Un-Protected 15 sectors +=>erase FFE10000 FFEFFFFF +Erase Flash from 0xffe10000 to 0xffefffff +Erase FLASH[F0_SA3(KERNEL)] -15 sectors:............... done +Erased 15 sectors +=>cp.b 100000 FFE10000 b7c4d +Copy to Flash... FLASH[F0_SA3(KERNEL)]:............done +=>bootm ffe10000 +## Booting image at ffe10000 ... + Image Name: vmlinux.bin.gz + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 752653 Bytes = 735 kB = 0 MB + Load Address: 00000000 + Entry Point: 00000000 + Verifying Checksum ... OK + Uncompressing Kernel Image ... OK +Total memory = 64MB; using 0kB for hash table (at 00000000) +Linux version 2.4.2_hhl20 (jfd@atlantis) (gcc version 2.95.2 19991024 (release)) #597 Wed Sep 5 23:23:23 PDT 2001 +cpu0: MPC8240/KAHLUA : MOUSSE Platform : 64MB RAM: MPLD Rev. 7f +Sandpoint port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com) +IP PNP: 802.3 Ethernet Address=<0:0:10:20:30:44> +NOTICE: mounting root file system via NFS +On node 0 totalpages: 16384 +zone(0): 16384 pages. +zone(1): 0 pages. +zone(2): 0 pages. +time_init: decrementer frequency = 16.665914 MHz +time_init: MPC8240 PCI Bus frequency = 33.331828 MHz +Calibrating delay loop... 133.12 BogoMIPS +Memory: 62436k available (1336k kernel code, 500k data, 88k init, 0k highmem) +Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes) +Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes) +Page-cache hash table entries: 16384 (order: 4, 65536 bytes) +Inode-cache hash table entries: 4096 (order: 3, 32768 bytes) +POSIX conformance testing by UNIFIX +PCI: Probing PCI hardware +Linux NET4.0 for Linux 2.4 +Based upon Swansea University Computer Society NET3.039 +Initializing RT netlink socket +Starting kswapd v1.8 +pty: 256 Unix98 ptys configured +block: queued sectors max/low 41394kB/13798kB, 128 slots per queue +Uniform Multi-Platform E-IDE driver Revision: 6.31 +ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx +PDC20262: IDE controller on PCI bus 00 dev 70 +PDC20262: chipset revision 1 +PDC20262: not 100% native mode: will probe irqs later +PDC20262: ROM enabled at 0x000d0000 +PDC20262: (U)DMA Burst Bit DISABLED Primary PCI Mode Secondary PCI Mode. +PDC20262: FORCING BURST BIT 0x00 -> 0x01 ACTIVE +PDC20262: irq=3 dev->irq=3 + ide0: BM-DMA at 0xbfff00-0xbfff07, BIOS settings: hda:DMA, hdb:DMA + ide1: BM-DMA at 0xbfff08-0xbfff0f, BIOS settings: hdc:pio, hdd:pio +hda: WDC WD300AB-00BVA0, ATA DISK drive +hdc: SONY CD-RW CRX160E, ATAPI CD/DVD-ROM drive +ide0 at 0xbfff78-0xbfff7f,0xbfff76 on irq 3 +ide1 at 0xbfff68-0xbfff6f,0xbfff66 on irq 3 +hda: 58633344 sectors (30020 MB) w/2048KiB Cache, CHS=58168/16/63, UDMA(66) +hdc: ATAPI 32X CD-ROM CD-R/RW drive, 4096kB Cache +Uniform CD-ROM driver Revision: 3.12 +Partition check: + /dev/ide/host0/bus0/target0/lun0: p1 p2 +hd: unable to get major 3 for hard disk +udf: registering filesystem +loop: loaded (max 8 devices) +Serial driver version 5.02 (2000-08-09) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled +ttyS00 at 0xffe08080 (irq = 4) is a ST16650 +Linux Tulip driver version 0.9.13a (January 20, 2001) +eth0: Digital DS21143 Tulip rev 65 at 0xbfff80, EEPROM not present, 00:00:10:20:30:44, IRQ 1. +eth0: MII transceiver #0 config 3000 status 7829 advertising 01e1. +NET4: Linux TCP/IP 1.0 for NET4.0 +IP Protocols: ICMP, UDP, TCP +IP: routing cache hash table of 512 buckets, 4Kbytes +TCP: Hash tables configured (established 4096 bind 4096) +NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. +devfs: v0.102 (20000622) Richard Gooch (rgooch@atnf.csiro.au) +devfs: boot_options: 0x0 +VFS: Mounted root (nfs filesystem). +Mounted devfs on /dev +Freeing unused kernel memory: 88k init 4k openfirmware +eth0: Setting full-duplex based on MII#0 link partner capability of 45e1. +INIT: version 2.78 booting +INIT: Entering runlevel: 2 + + +Welcome to Linux/PPC +MPC8240/MOUSSE + + +mousse login: root +Password: +PAM_unix[13]: (login) session opened for user root by LOGIN(uid=0) +Last login: Thu Sep 6 00:16:51 2001 on console + + +Welcome to Linux/PPC +MPC8240/MOUSSE + + +mousse# diff --git a/board/mousse/mousse.h b/board/mousse/mousse.h new file mode 100644 index 0000000..5468314 --- /dev/null +++ b/board/mousse/mousse.h @@ -0,0 +1,259 @@ +/* + * MOUSSE/MPC8240 Board definitions. + * For more info, see http://www.vooha.com/ + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 + * James Dougherty (jfd@cs.stanford.edu) + * + * 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 __MOUSSE_H +#define __MOUSSE_H + +/* System addresses */ + +#define PCI_SPECIAL_BASE 0xfe000000 +#define PCI_SPECIAL_SIZE 0x01000000 + +/* PORTX Device Addresses for Mousse */ + +#define PORTX_DEV_BASE 0xff000000 +#define PORTX_DEV_SIZE 0x01000000 + +#define ENET_DEV_BASE 0x80000000 + +#define PLD_REG_BASE (PORTX_DEV_BASE | 0xe09000) +#define PLD_REG(off) (*(volatile unsigned char *) \ + (PLD_REG_BASE + (off))) + +#define PLD_REVID_B1 0x7f +#define PLD_REVID_B2 0x01 + +/* MPLD */ +#define SYS_HARD_RESET() { for (;;) PLD_REG(0) = 0; } /* clr 0x80 bit */ +#define SYS_REVID_GET() ((int) PLD_REG(0) & 0x7f) +#define SYS_LED_OFF() (PLD_REG(1) |= 0x80) +#define SYS_LED_ON() (PLD_REG(1) &= ~0x80) +#define SYS_WATCHDOG_IRQ3() (PLD_REG(2) |= 0x80) +#define SYS_WATCHDOG_RESET() (PLD_REG(2) &= ~0x80) +#define SYS_TOD_PROTECT() (PLD_REG(3) |= 0x80) +#define SYS_TOD_UNPROTECT() (PLD_REG(3) &= ~0x80) + +/* SGS M48T59Y */ +#define TOD_BASE (PORTX_DEV_BASE | 0xe0a000) +#define TOD_REG_BASE (TOD_BASE | 0x1ff0) +#define TOD_NVRAM_BASE TOD_BASE +#define TOD_NVRAM_SIZE 0x1ff0 +#define TOD_NVRAM_LIMIT (TOD_NVRAM_BASE + TOD_NVRAM_SIZE) + +/* NS16552 SIO */ +#define SERIAL_BASE(_x) (PORTX_DEV_BASE | 0xe08000 | ((_x) ? 0 : 0x80)) +#define N_SIO_CHANNELS 2 +#define N_COM_PORTS N_SIO_CHANNELS + +/* + * On-board Dec21143 PCI Ethernet + * Note: The PCI MBAR chosen here was used from MPC8240UM which states + * that PCI memory is at: 0x80000 - 0xFDFFFFFF, if AMBOR[CPU_FD_ALIAS] + * is set, then PCI memory maps 1-1 with this address range in the + * correct byte order. + */ +#define PCI_ENET_IOADDR 0x80000000 +#define PCI_ENET_MEMADDR 0x80000000 + +/* + * Flash Memory Layout + * + * 2 MB Flash Bank 0 runs in 8-bit mode. In Flash Bank 0, the 32 kB + * sector SA3 is obscured by the 32 kB serial/TOD access space, and + * the 64 kB sectors SA19-SA26 are obscured by the 512 kB PLCC + * containing the fixed boot ROM. (If the 512 kB PLCC is + * deconfigured by jumper, this window to Flash Bank 0 becomes + * visible, but it still contains the fixed boot code and should be + * considered read-only). Flash Bank 0 sectors SA0 (16 kB), SA1 (8 + * kB), and SA2 (8 kB) are currently unused. + * + * 2 MB Flash Bank 1 runs in 16-bit mode. Flash Bank 1 is fully + * usable, but it's a 16-bit wide device on a 64-bit bus. Therefore + * 16-bit words only exist at addresses that are multiples of 8. All + * PROM data and control addresses must be multiplied by 8. + * + * See flashMap.c for description of flash filesystem layout. + */ + +/* + * FLASH memory address space: 8-bit wide FLASH memory spaces. + */ +#define FLASH0_SEG0_START 0xffe00000 /* Baby 32Kb segment */ +#define FLASH0_SEG0_END 0xffe07fff /* 16 kB + 8 kB + 8 kB */ +#define FLASH0_SEG0_SIZE 0x00008000 /* (sectors SA0-SA2) */ + +#define FLASH0_SEG1_START 0xffe10000 /* 1MB - 64Kb FLASH0 seg */ +#define FLASH0_SEG1_END 0xffefffff /* 960 kB */ +#define FLASH0_SEG1_SIZE 0x000f0000 + +#define FLASH0_SEG2_START 0xfff00000 /* Boot Loader stored here */ +#define FLASH0_SEG2_END 0xfff7ffff /* 512 kB FLASH0/PLCC seg */ +#define FLASH0_SEG2_SIZE 0x00080000 + +#define FLASH0_SEG3_START 0xfff80000 /* 512 kB FLASH0 seg */ +#define FLASH0_SEG3_END 0xffffffff +#define FLASH0_SEG3_SIZE 0x00080000 + +/* Where Kahlua starts */ +#define FLASH_RESET_VECT 0xfff00100 + +/* + * CHRP / PREP (MAP A/B) definitions. + */ + +#define PREP_REG_ADDR 0x80000cf8 /* MPC107 Config, Map A */ +#define PREP_REG_DATA 0x80000cfc /* MPC107 Config, Map A */ +/* MPC107 (MPC8240 internal EUMBBAR mapped) */ +#define CHRP_REG_ADDR 0xfec00000 /* MPC106 Config, Map B */ +#define CHRP_REG_DATA 0xfee00000 /* MPC106 Config, Map B */ + +/* + * Mousse PCI IDSEL Assignments (Device Number) + */ +#define MOUSSE_IDSEL_ENET 13 /* On-board 21143 Ethernet */ +#define MOUSSE_IDSEL_LPCI 14 /* On-board PCI slot */ +#define MOUSSE_IDSEL_82371 15 /* That other thing */ +#define MOUSSE_IDSEL_CPCI2 31 /* CPCI slot 2 */ +#define MOUSSE_IDSEL_CPCI3 30 /* CPCI slot 3 */ +#define MOUSSE_IDSEL_CPCI4 29 /* CPCI slot 4 */ +#define MOUSSE_IDSEL_CPCI5 28 /* CPCI slot 5 */ +#define MOUSSE_IDSEL_CPCI6 27 /* CPCI slot 6 */ + +/* + * Mousse Interrupt Mapping: + * + * IRQ1 Enet (intA|intB|intC|intD) + * IRQ2 CPCI intA (See below) + * IRQ3 Local PCI slot intA|intB|intC|intD + * IRQ4 COM1 Serial port (Actually higher addressed port on duart) + * + * PCI Interrupt Mapping in CPCI chassis: + * + * | CPCI Slot + * | 1 (CPU) 2 3 4 5 6 + * -----------+--------+-------+-------+-------+-------+-------+ + * intA | X X X + * intB | X X X + * intC | X X X + * intD | X X X + */ + + +#define EPIC_VECTOR_EXT0 0 +#define EPIC_VECTOR_EXT1 1 +#define EPIC_VECTOR_EXT2 2 +#define EPIC_VECTOR_EXT3 3 +#define EPIC_VECTOR_EXT4 4 +#define EPIC_VECTOR_TM0 16 +#define EPIC_VECTOR_TM1 17 +#define EPIC_VECTOR_TM2 18 +#define EPIC_VECTOR_TM3 19 +#define EPIC_VECTOR_I2C 20 +#define EPIC_VECTOR_DMA0 21 +#define EPIC_VECTOR_DMA1 22 +#define EPIC_VECTOR_I2O 23 + + +#define INT_VEC_IRQ0 0 +#define INT_NUM_IRQ0 INT_VEC_IRQ0 +#define MOUSSE_IRQ_ENET EPIC_VECTOR_EXT1 /* Hardwired */ +#define MOUSSE_IRQ_CPCI EPIC_VECTOR_EXT2 /* Hardwired */ +#define MOUSSE_IRQ_LPCI EPIC_VECTOR_EXT3 /* Hardwired */ +#define MOUSSE_IRQ_DUART EPIC_VECTOR_EXT4 /* Hardwired */ + +/* Onboard DEC 21143 Ethernet */ +#define PCI_ENET_MEMADDR 0x80000000 +#define PCI_ENET_IOADDR 0x80000000 + +/* Some other PCI device */ +#define PCI_SLOT_MEMADDR 0x81000000 +#define PCI_SLOT_IOADDR 0x81000000 + +/* Promise ATA66 PCI Device (ATA controller) */ +#define PROMISE_MBAR0 0xa0000000 +#define PROMISE_MBAR1 (PROMISE_MBAR0 + 0x1000) +#define PROMISE_MBAR2 (PROMISE_MBAR0 + 0x2000) +#define PROMISE_MBAR3 (PROMISE_MBAR0 + 0x3000) +#define PROMISE_MBAR4 (PROMISE_MBAR0 + 0x4000) +#define PROMISE_MBAR5 (PROMISE_MBAR0 + 0x5000) + +/* ATA/66 Controller offsets */ +#define CFG_ATA_BASE_ADDR PROMISE_MBAR0 +#define CFG_IDE_MAXBUS 2 /* ide0/ide1 */ +#define CFG_IDE_MAXDEVICE 2 /* 2 drives per controller */ +#define CFG_ATA_IDE0_OFFSET 0 +#define CFG_ATA_IDE1_OFFSET 0x3000 +/* + * Definitions for accessing IDE controller registers + */ +#define CFG_ATA_DATA_OFFSET 0 +#define CFG_ATA_REG_OFFSET 0 +#define CFG_ATA_ALT_OFFSET (0x1000) + +/* + * The constants ROM_TEXT_ADRS, ROM_SIZE, RAM_HIGH_ADRS, and RAM_LOW_ADRS + * are defined in config.h and Makefile. + * All definitions for these constants must be identical. + */ +#define ROM_BASE_ADRS 0xfff00000 /* base address of ROM */ +#define ROM_TEXT_ADRS (ROM_BASE_ADRS+0x0100) /* with PC & SP */ +#define ROM_WARM_ADRS (ROM_TEXT_ADRS+0x0004) /* warm reboot entry */ +#define ROM_SIZE 0x00080000 /* 512KB ROM space */ +#define RAM_LOW_ADRS 0x00010000 /* RAM address for vxWorks */ +#define RAM_HIGH_ADRS 0x00c00000 /* RAM address for bootrom */ + +/* + * NVRAM configuration + * NVRAM is implemented via the SGS Thomson M48T59Y + * 64Kbit (8Kbx8) Timekeeper SRAM. + * This 8KB NVRAM also has a TOD. See m48t59y.{h,c} for more information. + */ + +#define NV_RAM_ADRS TOD_NVRAM_BASE +#define NV_RAM_INTRVL 1 +#define NV_RAM_WR_ENBL SYS_TOD_UNPROTECT() +#define NV_RAM_WR_DSBL SYS_TOD_PROTECT() + +#define NV_OFF_BOOT0 0x0000 /* Boot string 0 (256b) */ +#define NV_OFF_BOOT1 0x0100 /* Boot string 1 (256b) */ +#define NV_OFF_BOOT2 0x0200 /* Boot string 2 (256b)*/ +#define NV_OFF_MACADDR 0x0400 /* 21143 MAC address (6b) */ +#define NV_OFF_ACTIVEBOOT 0x0406 /* Active boot string, 0 to 2 (1b) */ +#define NV_OFF_UNUSED1 0x0407 /* Unused (1b) */ +#define NV_OFF_BINDFIX 0x0408 /* See sysLib.c:sysBindFix() (1b) */ +#define NV_OFF_UNUSED2 0x0409 /* Unused (7b) */ +#define NV_OFF_TIMEZONE 0x0410 /* TIMEZONE env var (64b) */ +#define NV_OFF_VXWORKS_END 0x07FF /* 2047 VxWorks Total */ +#define NV_OFF_U_BOOT 0x0800 /* 2048 U-Boot boot-loader */ +#define NV_OFF_U_BOOT_ADDR (TOD_BASE + NV_OFF_U_BOOT) /* sysaddr*/ +#define NV_U_BOOT_ENV_SIZE 2048 /* 2K - U-Boot Total */ +#define NV_OFF__next_free (NV_U_BOOT_ENVSIZE +1) +#define NV_RAM_SIZE 8176 /* NVRAM End */ + +#endif /* __MOUSSE_H */ diff --git a/board/mvs1/README b/board/mvs1/README new file mode 100644 index 0000000..6c66d67 --- /dev/null +++ b/board/mvs1/README @@ -0,0 +1,15 @@ +This port is for the MATRIX Vision mvSensor. +It is an mpc823-based universal image processing board +with CMOS or CCD sensor, 4MB FLASH and 16-64MB RAM. + +See http://www.matrix-vision.de for more details or mail... + +mvsensor@matrix-vision.de + +Howard Gray +MATRIX Vision GmbH +Talstr. 16 +D-71570 +Oppenweiler +Germany + diff --git a/board/mvs1/mvs1.c b/board/mvs1/mvs1.c new file mode 100644 index 0000000..da98de5 --- /dev/null +++ b/board/mvs1/mvs1.c @@ -0,0 +1,404 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Changes for MATRIX Vision MVsensor (C) Copyright 2001 + * MATRIX Vision GmbH / hg, info@matrix-vision.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc8xx.h> + +/* ------------------------------------------------------------------------- */ + +static long int dram_size (long int, long int *, long int); + +/* ------------------------------------------------------------------------- */ + +#define _NOT_USED_ 0xFFFFFFFF + +const uint sdram_table[] = +{ + /* + * Single Read. (Offset 0 in UPMA RAM) + */ + 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00, + 0x1FF5FC47, /* last */ + /* + * SDRAM Initialization (offset 5 in UPMA RAM) + * + * This is no UPM entry point. The following definition uses + * the remaining space to establish an initialization + * sequence, which is executed by a RUN command. + * + */ + 0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */ + /* + * Burst Read. (Offset 8 in UPMA RAM) + */ + 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00, + 0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Single Write. (Offset 18 in UPMA RAM) + */ + 0x1F0DFC04 /*0x1F2DFC04??*/, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Burst Write. (Offset 20 in UPMA RAM) + */ + 0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00, + 0xF0AFFC00, 0xE1BAFC04, 0x1FF5FC47, /* last */ + _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Refresh (Offset 30 in UPMA RAM) + */ + 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, + 0xFFFFFC84, 0xFFFFFC07, /* last */ + _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* + * Exception. (Offset 3c in UPMA RAM) + */ + 0x7FFFFC07, /* last */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, +}; + +/* ------------------------------------------------------------------------- */ + + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + puts ("Board: MATRIX Vision MVsensor\n"); + return 0; +} + + + +#ifdef DO_RAM_TEST +/* ------------------------------------------------------------------------- */ + +/* + * Test SDRAM by writing its address to itself and reading several times +*/ +#define READ_RUNS 4 +static void test_dram (unsigned long *start, unsigned long *end) +{ + unsigned long *addr; + unsigned long value; + int read_runs, errors, addr_errors; + + printf ("\nChecking SDRAM from %p to %p\n", start, end); + udelay (1000000); + for (addr = start; addr < end; addr++) + *addr = (unsigned long) addr; + + for (addr = start, addr_errors = 0; addr < end; addr++) { + for (read_runs = READ_RUNS, errors = 0; read_runs > 0; read_runs--) { + if ((value = *addr) != (unsigned long) addr) + errors++; + } + if (errors > 0) { + addr_errors++; + printf ("SDRAM errors (%d) at %p, last read = %ld\n", + errors, addr, value); + udelay (10000); + } + } + printf ("SDRAM check finished, total errors = %d\n", addr_errors); +} +#endif /* DO_RAM_TEST */ + + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + long int size_b0, size_b1, size8, size9; + + upmconfig (UPMA, (uint *) sdram_table, + sizeof (sdram_table) / sizeof (uint)); + + /* + * Preliminary prescaler for refresh (depends on number of + * banks): This value is selected for four cycles every 62.4 us + * with two SDRAM banks or four cycles every 31.2 us with one + * bank. It will be adjusted after memory sizing. + */ + memctl->memc_mptpr = CFG_MPTPR_2BK_8K; + + memctl->memc_mar = 0x00000088; + + /* + * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at + * preliminary addresses - these have to be modified after the + * SDRAM size has been determined. + */ + memctl->memc_or2 = CFG_OR2_PRELIM; + memctl->memc_br2 = CFG_BR2_PRELIM; + +#if defined (CFG_OR3_PRELIM) && defined (CFG_BR3_PRELIM) + if (board_type == 0) { /* "L" type boards have only one bank SDRAM */ + memctl->memc_or3 = CFG_OR3_PRELIM; + memctl->memc_br3 = CFG_BR3_PRELIM; + } +#endif + + memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */ + + udelay (200); + + /* perform SDRAM initializsation sequence */ + + memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */ + udelay (1); + memctl->memc_mcr = 0x80004230; /* SDRAM bank 0 - execute twice */ + udelay (1); + + if (board_type == 0) { /* "L" type boards have only one bank SDRAM */ + memctl->memc_mcr = 0x80006105; /* SDRAM bank 1 */ + udelay (1); + memctl->memc_mcr = 0x80006230; /* SDRAM bank 1 - execute twice */ + udelay (1); + } + + memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */ + + udelay (1000); + + /* + * Check Bank 0 Memory Size for re-configuration + * + * try 8 column mode + */ + size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE2_PRELIM, + SDRAM_MAX_SIZE); + + udelay (1000); + /* + * try 9 column mode + */ + size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE2_PRELIM, + SDRAM_MAX_SIZE); + + if (size8 < size9) { /* leave configuration at 9 columns */ + size_b0 = size9; + } else { /* back to 8 columns */ + size_b0 = size8; + memctl->memc_mamr = CFG_MAMR_8COL; + udelay (500); + } + + if (board_type == 0) { /* "L" type boards have only one bank SDRAM */ + /* + * Check Bank 1 Memory Size + * use current column settings + * [9 column SDRAM may also be used in 8 column mode, + * but then only half the real size will be used.] + */ +#if defined (SDRAM_BASE3_PRELIM) + size_b1 = + dram_size (memctl->memc_mamr, (ulong *) SDRAM_BASE3_PRELIM, + SDRAM_MAX_SIZE); +#else + size_b1 = 0; +#endif + } else { + size_b1 = 0; + } + + udelay (1000); + + /* + * Adjust refresh rate depending on SDRAM type, both banks + * For types > 128 MBit leave it at the current (fast) rate + */ + if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) { + /* reduce to 15.6 us (62.4 us / quad) */ + memctl->memc_mptpr = CFG_MPTPR_2BK_4K; + udelay (1000); + } + + /* + * Final mapping: map bigger bank first + */ + if (size_b1 > size_b0) { /* SDRAM Bank 1 is bigger - map first */ + + memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; + memctl->memc_br3 = + (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; + + if (size_b0 > 0) { + /* + * Position Bank 0 immediately above Bank 1 + */ + memctl->memc_or2 = + ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; + memctl->memc_br2 = + ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V) + + size_b1; + } else { + unsigned long reg; + + /* + * No bank 0 + * + * invalidate bank + */ + memctl->memc_br2 = 0; + + /* adjust refresh rate depending on SDRAM type, one bank */ + reg = memctl->memc_mptpr; + reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */ + memctl->memc_mptpr = reg; + } + + } else { /* SDRAM Bank 0 is bigger - map first */ + + memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; + memctl->memc_br2 = + (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; + + if (size_b1 > 0) { + /* + * Position Bank 1 immediately above Bank 0 + */ + memctl->memc_or3 = + ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; + memctl->memc_br3 = + ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V) + + size_b0; + } else { + unsigned long reg; + + /* + * No bank 1 + * + * invalidate bank + */ + memctl->memc_br3 = 0; + + /* adjust refresh rate depending on SDRAM type, one bank */ + reg = memctl->memc_mptpr; + reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */ + memctl->memc_mptpr = reg; + } + } + + udelay (10000); + +#ifdef DO_RAM_TEST + if (size_b0 > 0) + test_dram ((unsigned long *) CFG_SDRAM_BASE, + (unsigned long *) (CFG_SDRAM_BASE + size_b0)); +#endif + + return (size_b0 + size_b1); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check memory range for valid RAM. A simple memory test determines + * the actually available RAM size between addresses `base' and + * `base + maxsize'. Some (not all) hardware errors are detected: + * - short between address lines + * - short between data lines + */ + +static long int dram_size (long int mamr_value, long int *base, + long int maxsize) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + volatile long int *addr; + long int cnt, val; + + + memctl->memc_mamr = mamr_value; + + for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) { + addr = base + cnt; /* pointer arith! */ + + *addr = ~cnt; + } + + /* write 0 to base address */ + addr = base; + *addr = 0; + + /* check at base address */ + if ((val = *addr) != 0) { + return (0); + } + + for (cnt = 1;; cnt <<= 1) { + addr = base + cnt; /* pointer arith! */ + + val = *addr; + + if (val != (~cnt)) { + return (cnt * sizeof (long)); + } + } + /* NOTREACHED */ +} + + +/* ------------------------------------------------------------------------- */ + +u8 *dhcp_vendorex_prep (u8 * e) +{ + char *ptr; + +/* DHCP vendor-class-identifier = 60 */ + if ((ptr = getenv ("dhcp_vendor-class-identifier"))) { + *e++ = 60; + *e++ = strlen (ptr); + while (*ptr) + *e++ = *ptr++; + } +/* my DHCP_CLIENT_IDENTIFIER = 61 */ + if ((ptr = getenv ("dhcp_client_id"))) { + *e++ = 61; + *e++ = strlen (ptr); + while (*ptr) + *e++ = *ptr++; + } + + return e; +} + + +/* ------------------------------------------------------------------------- */ +u8 *dhcp_vendorex_proc (u8 * popt) +{ + return NULL; +} diff --git a/board/ppmc8260/ppmc8260.c b/board/ppmc8260/ppmc8260.c new file mode 100644 index 0000000..ab32622 --- /dev/null +++ b/board/ppmc8260/ppmc8260.c @@ -0,0 +1,307 @@ +/* + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +const iop_conf_t iop_conf_tab[4][32] = { + + + /* Port A configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 *ATMTXEN */ + /* PA30 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTCA */ + /* PA29 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTSOC */ + /* PA28 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 *ATMRXEN */ + /* PA27 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRSOC */ + /* PA26 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRCA */ + /* PA25 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[0] */ + /* PA24 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[1] */ + /* PA23 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[2] */ + /* PA22 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[3] */ + /* PA21 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[4] */ + /* PA20 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[5] */ + /* PA19 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[6] */ + /* PA18 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[7] */ + /* PA17 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */ + /* PA16 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */ + /* PA15 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */ + /* PA14 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */ + /* PA13 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */ + /* PA12 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */ + /* PA11 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */ + /* PA10 */ { 0, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */ + /* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */ + /* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */ + /* PA7 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_A1:L1TSYNC */ + /* PA6 */ { 1, 0, 0, 1, 0, 0 }, /* TDN_A1:L1RSYNC */ + /* PA5 */ { 0, 0, 0, 0, 0, 0 }, /* PA5 */ + /* PA4 */ { 0, 0, 0, 0, 0, 0 }, /* PA4 */ + /* PA3 */ { 0, 0, 0, 0, 0, 0 }, /* PA3 */ + /* PA2 */ { 0, 0, 0, 0, 0, 0 }, /* PA2 */ + /* PA1 */ { 0, 0, 0, 0, 0, 0 }, /* PA1 */ + /* PA0 */ { 0, 0, 0, 0, 0, 0 } /* PA0 */ + }, + + /* Port B configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ + /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ + /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ + /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ + /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ + /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ + /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ + /* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */ + /* PB16 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_A1:L1CLK0 */ + /* PB15 */ { 1, 0, 0, 1, 0, 1 }, /* /FETHRST */ + /* PB14 */ { 1, 0, 0, 1, 0, 0 }, /* FETHDIS */ + /* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* PB13 */ + /* PB12 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_B1:L1CLK0 */ + /* PB11 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1TXD */ + /* PB10 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1RXD */ + /* PB9 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1TSYNC */ + /* PB8 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_D1:L1RSYNC */ + /* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */ + /* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* PB6 */ + /* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* PB5 */ + /* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* PB4 */ + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 0, 0, 0, 0, 0, 0 }, /* PC31 */ + /* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* PC30 */ + /* PC29 */ { 0, 0, 0, 0, 0, 0 }, /* PC28 */ + /* PC28 */ { 1, 1, 0, 0, 0, 0 }, /* CLK4 */ + /* PC27 */ { 0, 0, 0, 0, 0, 0 }, /* PC27 */ + /* PC26 */ { 0, 0, 0, 0, 0, 0 }, /* PC26 */ + /* PC25 */ { 1, 1, 0, 0, 0, 0 }, /* CLK7 */ + /* PC24 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */ + /* PC23 */ { 1, 0, 0, 1, 0, 0 }, /* ATMTFCLK */ + /* PC22 */ { 0, 0, 0, 0, 0, 0 }, /* PC22 */ + /* PC21 */ { 0, 0, 0, 0, 0, 0 }, /* PC23 */ + /* PC20 */ { 0, 0, 0, 0, 0, 0 }, /* PC24 */ + /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */ + /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */ + /* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* PC17 */ + /* PC16 */ { 0, 0, 0, 0, 0, 0 }, /* PC16 */ + /* PC15 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:TxAddr[0] */ + /* PC14 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[0] */ + /* PC13 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:TxAddr[1] */ + /* PC12 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[1] */ + /* PC11 */ { 1, 1, 0, 1, 0, 0 }, /* TDM_D1:L1CLK0 */ + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDC */ + /* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */ + /* PC8 */ { 0, 0, 0, 0, 0, 0 }, /* PC8 */ + /* PC7 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:TxAddr[2]*/ + /* PC6 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[2] */ + /* PC5 */ { 0, 0, 0, 0, 0, 0 }, /* PC5 */ + /* PC4 */ { 0, 0, 0, 0, 0, 0 }, /* PC4 */ + /* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA2:DACK */ + /* PC2 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA2:DONE */ + /* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA2:DREQ */ + /* PC0 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA1:DREQ */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 0, 0, 0, 0, 0, 0 }, /* PD31 */ + /* PD30 */ { 0, 0, 0, 0, 0, 0 }, /* PD30 */ + /* PD29 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1:RxAddr[3] */ + /* PD28 */ { 0, 0, 0, 0, 0, 0 }, /* PD28 */ + /* PD27 */ { 0, 0, 0, 0, 0, 0 }, /* PD27 */ + /* PD26 */ { 1, 0, 0, 1, 0, 0 }, /* TDM_C1:L1RSYNC */ + /* PD25 */ { 0, 0, 0, 0, 0, 0 }, /* PD25 */ + /* PD24 */ { 0, 0, 0, 0, 0, 0 }, /* PD24 */ + /* PD23 */ { 0, 0, 0, 0, 0, 0 }, /* PD23 */ + /* PD22 */ { 0, 0, 0, 0, 0, 0 }, /* PD22 */ + /* PD21 */ { 0, 0, 0, 0, 0, 0 }, /* PD21 */ + /* PD20 */ { 0, 0, 0, 0, 0, 0 }, /* PD20 */ + /* PD19 */ { 0, 0, 0, 0, 0, 0 }, /* PD19 */ + /* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD19 */ + /* PD17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ + /* PD16 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ + /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ + /* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1TXD */ + /* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1RXD */ + /* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1TSYNC */ + /* PD10 */ { 1, 0, 0, 0, 0, 0 }, /* TDM_B1:L1RSYNC*/ + /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1:TXD */ + /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1:RXD */ + /* PD7 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1:SMSYN */ + /* PD6 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA1:DACK */ + /* PD5 */ { 1, 0, 0, 1, 0, 0 }, /* IDMA1:DONE */ + /* PD4 */ { 0, 0, 0, 0, 0, 0 }, /* PD4 */ + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + } +}; + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + puts ("Board: Wind River PPMC8260\n"); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar c = 0xff; + volatile uchar *ramaddr0 = (uchar *) (CFG_SDRAM0_BASE); + volatile uchar *ramaddr1 = (uchar *) (CFG_SDRAM1_BASE); + ulong psdmr = CFG_PSDMR; + volatile uchar *ramaddr2 = (uchar *) (CFG_SDRAM2_BASE); + ulong lsdmr = CFG_LSDMR; + int i; + + /* + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): + * + * "At system reset, initialization software must set up the + * programmable parameters in the memory controller banks registers + * (ORx, BRx, P/LSDMR). After all memory parameters are configured, + * system software should execute the following initialization sequence + * for each SDRAM device. + * + * 1. Issue a PRECHARGE-ALL-BANKS command + * 2. Issue eight CBR REFRESH commands + * 3. Issue a MODE-SET command to initialize the mode register + * + * The initial commands are executed by setting P/LSDMR[OP] and + * accessing the SDRAM with a single-byte transaction." + * + * The appropriate BRx/ORx registers have already been set when we + * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE. + */ + + memctl->memc_psrt = CFG_PSRT; + memctl->memc_mptpr = CFG_MPTPR; + +#ifndef CFG_RAMBOOT + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; + *ramaddr0++ = c; + *ramaddr1++ = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) { + *ramaddr0++ = c; + *ramaddr1++ = c; + } + + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; + ramaddr0 = (uchar *) (CFG_SDRAM0_BASE + 0x110); + ramaddr1 = (uchar *) (CFG_SDRAM1_BASE + 0x110); + *ramaddr0 = c; + *ramaddr1 = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr0 = c; + *ramaddr1 = c; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_PREA; + *ramaddr2++ = c; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) { + *ramaddr2++ = c; + } + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_MRW; + *ramaddr2++ = c; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr2 = c; +#endif + + /* return total ram size */ + return ((CFG_SDRAM0_SIZE + CFG_SDRAM1_SIZE) * 1024 * 1024); +} + +#ifdef CONFIG_MISC_INIT_R +/* ------------------------------------------------------------------------- */ +int misc_init_r (void) +{ +#ifdef CFG_LED_BASE + uchar ds = *(unsigned char *) (CFG_LED_BASE + 1); + uchar ss; + uchar tmp[64]; + int res; + + if ((ds != 0) && (ds != 0xff)) { + res = getenv_r ("ethaddr", tmp, sizeof (tmp)); + if (res > 0) { + ss = ((ds >> 4) & 0x0f); + ss += ss < 0x0a ? '0' : ('a' - 10); + tmp[15] = ss; + + ss = (ds & 0x0f); + ss += ss < 0x0a ? '0' : ('a' - 10); + tmp[16] = ss; + + tmp[17] = '\0'; + setenv ("ethaddr", tmp); + /* set the led to show the address */ + *((unsigned char *) (CFG_LED_BASE + 1)) = ds; + } + } +#endif /* CFG_LED_BASE */ + return (0); +} +#endif /* CONFIG_MISC_INIT_R */ diff --git a/board/ppmc8260/strataflash.c b/board/ppmc8260/strataflash.c new file mode 100644 index 0000000..bb21848 --- /dev/null +++ b/board/ppmc8260/strataflash.c @@ -0,0 +1,755 @@ +/* + * (C) Copyright 2002 + * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc8260.h> +#include <asm/processor.h> + +#undef DEBUG_FLASH +/* + * This file implements a Common Flash Interface (CFI) driver for U-Boot. + * The width of the port and the width of the chips are determined at initialization. + * These widths are used to calculate the address for access CFI data structures. + * It has been tested on an Intel Strataflash implementation. + * + * References + * JEDEC Standard JESD68 - Common Flash Interface (CFI) + * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes + * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets + * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet + * + * TODO + * Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available + * Add support for other command sets Use the PRI and ALT to determine command set + * Verify erase and program timeouts. + */ + +#define FLASH_CMD_CFI 0x98 +#define FLASH_CMD_READ_ID 0x90 +#define FLASH_CMD_RESET 0xff +#define FLASH_CMD_BLOCK_ERASE 0x20 +#define FLASH_CMD_ERASE_CONFIRM 0xD0 +#define FLASH_CMD_WRITE 0x40 +#define FLASH_CMD_PROTECT 0x60 +#define FLASH_CMD_PROTECT_SET 0x01 +#define FLASH_CMD_PROTECT_CLEAR 0xD0 +#define FLASH_CMD_CLEAR_STATUS 0x50 +#define FLASH_CMD_WRITE_TO_BUFFER 0xE8 +#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0 + +#define FLASH_STATUS_DONE 0x80 +#define FLASH_STATUS_ESS 0x40 +#define FLASH_STATUS_ECLBS 0x20 +#define FLASH_STATUS_PSLBS 0x10 +#define FLASH_STATUS_VPENS 0x08 +#define FLASH_STATUS_PSS 0x04 +#define FLASH_STATUS_DPS 0x02 +#define FLASH_STATUS_R 0x01 +#define FLASH_STATUS_PROTECT 0x01 + +#define FLASH_OFFSET_CFI 0x55 +#define FLASH_OFFSET_CFI_RESP 0x10 +#define FLASH_OFFSET_WTOUT 0x1F +#define FLASH_OFFSET_WBTOUT 0x20 +#define FLASH_OFFSET_ETOUT 0x21 +#define FLASH_OFFSET_CETOUT 0x22 +#define FLASH_OFFSET_WMAX_TOUT 0x23 +#define FLASH_OFFSET_WBMAX_TOUT 0x24 +#define FLASH_OFFSET_EMAX_TOUT 0x25 +#define FLASH_OFFSET_CEMAX_TOUT 0x26 +#define FLASH_OFFSET_SIZE 0x27 +#define FLASH_OFFSET_INTERFACE 0x28 +#define FLASH_OFFSET_BUFFER_SIZE 0x2A +#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C +#define FLASH_OFFSET_ERASE_REGIONS 0x2D +#define FLASH_OFFSET_PROTECT 0x02 +#define FLASH_OFFSET_USER_PROTECTION 0x85 +#define FLASH_OFFSET_INTEL_PROTECTION 0x81 + + +#define FLASH_MAN_CFI 0x01000000 + + + + +typedef union { + unsigned char c; + unsigned short w; + unsigned long l; +} cfiword_t; + +typedef union { + unsigned char * cp; + unsigned short *wp; + unsigned long *lp; +} cfiptr_t; + +#define NUM_ERASE_REGIONS 4 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + + +/*----------------------------------------------------------------------- + * Functions + */ + + + +static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c); +static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf); +static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd); +static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd); +static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd); +static int flash_detect_cfi(flash_info_t * info); +static ulong flash_get_size (ulong base, int banknum); +static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword); +static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt); +#ifdef CFG_FLASH_USE_BUFFER_WRITE +static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len); +#endif +/*----------------------------------------------------------------------- + * create an address based on the offset and the port width + */ +inline uchar * flash_make_addr(flash_info_t * info, int sect, int offset) +{ + return ((uchar *)(info->start[sect] + (offset * info->portwidth))); +} +/*----------------------------------------------------------------------- + * read a character at a port width address + */ +inline uchar flash_read_uchar(flash_info_t * info, uchar offset) +{ + uchar *cp; + cp = flash_make_addr(info, 0, offset); + return (cp[info->portwidth - 1]); +} + +/*----------------------------------------------------------------------- + * read a short word by swapping for ppc format. + */ +ushort flash_read_ushort(flash_info_t * info, int sect, uchar offset) +{ + uchar * addr; + + addr = flash_make_addr(info, sect, offset); + return ((addr[(2*info->portwidth) - 1] << 8) | addr[info->portwidth - 1]); + +} + +/*----------------------------------------------------------------------- + * read a long word by picking the least significant byte of each maiximum + * port size word. Swap for ppc format. + */ +ulong flash_read_long(flash_info_t * info, int sect, uchar offset) +{ + uchar * addr; + + addr = flash_make_addr(info, sect, offset); + return ( (addr[(2*info->portwidth) - 1] << 24 ) | (addr[(info->portwidth) -1] << 16) | + (addr[(4*info->portwidth) - 1] << 8) | addr[(3*info->portwidth) - 1]); + +} + +/*----------------------------------------------------------------------- + */ +unsigned long flash_init (void) +{ + unsigned long size; + int i; + unsigned long address; + + + /* The flash is positioned back to back, with the demultiplexing of the chip + * based on the A24 address line. + * + */ + + address = CFG_FLASH_BASE; + size = 0; + + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + size += flash_info[i].size = flash_get_size(address, i); + address += CFG_FLASH_INCREMENT; + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",i, + flash_info[0].size, flash_info[i].size<<20); + } + } + + /* Monitor protection ON by default */ +#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE) + for(i=0; flash_info[0].start[i] < CFG_MONITOR_BASE+CFG_MONITOR_LEN-1; i++) + (void)flash_real_protect(&flash_info[0], i, 1); +#endif + + return (size); +} + +/*----------------------------------------------------------------------- + */ +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + int rcode = 0; + int prot; + int sect; + + if( info->flash_id != FLASH_MAN_CFI) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + if ((s_first < 0) || (s_first > s_last)) { + printf ("- no sectors to erase\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS); + flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE); + flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM); + + if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) { + rcode = 1; + } else + printf("."); + } + } + printf (" done\n"); + return rcode; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id != FLASH_MAN_CFI) { + printf ("missing or unknown FLASH type\n"); + return; + } + + printf("CFI conformant FLASH (%d x %d)", + (info->portwidth << 3 ), (info->chipwidth << 3 )); + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n", + info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n"); + printf (" %08lX%5s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong wp; + ulong cp; + int aln; + cfiword_t cword; + int i, rc; + + /* get lower aligned address */ + wp = (addr & ~(info->portwidth - 1)); + + /* handle unaligned start */ + if((aln = addr - wp) != 0) { + cword.l = 0; + cp = wp; + for(i=0;i<aln; ++i, ++cp) + flash_add_byte(info, &cword, (*(uchar *)cp)); + + for(; (i< info->portwidth) && (cnt > 0) ; i++) { + flash_add_byte(info, &cword, *src++); + cnt--; + cp++; + } + for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp) + flash_add_byte(info, &cword, (*(uchar *)cp)); + if((rc = flash_write_cfiword(info, wp, cword)) != 0) + return rc; + wp = cp; + } + +#ifdef CFG_FLASH_USE_BUFFER_WRITE + while(cnt >= info->portwidth) { + i = info->buffer_size > cnt? cnt: info->buffer_size; + if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK) + return rc; + wp += i; + src += i; + cnt -=i; + } +#else + /* handle the aligned part */ + while(cnt >= info->portwidth) { + cword.l = 0; + for(i = 0; i < info->portwidth; i++) { + flash_add_byte(info, &cword, *src++); + } + if((rc = flash_write_cfiword(info, wp, cword)) != 0) + return rc; + wp += info->portwidth; + cnt -= info->portwidth; + } +#endif /* CFG_FLASH_USE_BUFFER_WRITE */ + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + cword.l = 0; + for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) { + flash_add_byte(info, &cword, *src++); + --cnt; + } + for (; i<info->portwidth; ++i, ++cp) { + flash_add_byte(info, & cword, (*(uchar *)cp)); + } + + return flash_write_cfiword(info, wp, cword); +} + +/*----------------------------------------------------------------------- + */ +int flash_real_protect(flash_info_t *info, long sector, int prot) +{ + int retcode = 0; + + flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS); + flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT); + if(prot) + flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET); + else + flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR); + + if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout, + prot?"protect":"unprotect")) == 0) { + + info->protect[sector] = prot; + /* Intel's unprotect unprotects all locking */ + if(prot == 0) { + int i; + for(i = 0 ; i<info->sector_count; i++) { + if(info->protect[i]) + flash_real_protect(info, i, 1); + } + } + } + + return retcode; +} +/*----------------------------------------------------------------------- + * wait for XSR.7 to be set. Time out with an error if it does not. + * This routine does not set the flash to read-array mode. + */ +static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt) +{ + ulong start; + + /* Wait for command completion */ + start = get_timer (0); + while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) { + if (get_timer(start) > info->erase_blk_tout) { + printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]); + flash_write_cmd(info, sector, 0, FLASH_CMD_RESET); + return ERR_TIMOUT; + } + } + return ERR_OK; +} +/*----------------------------------------------------------------------- + * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check. + * This routine sets the flash to read-array mode. + */ +static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt) +{ + int retcode; + retcode = flash_status_check(info, sector, tout, prompt); + if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) { + retcode = ERR_INVAL; + printf("Flash %s error at address %lx\n", prompt,info->start[sector]); + if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){ + printf("Command Sequence Error.\n"); + } else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){ + printf("Block Erase Error.\n"); + retcode = ERR_NOT_ERASED; + } else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) { + printf("Locking Error\n"); + } + if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){ + printf("Block locked.\n"); + retcode = ERR_PROTECTED; + } + if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS)) + printf("Vpp Low Error.\n"); + } + flash_write_cmd(info, sector, 0, FLASH_CMD_RESET); + return retcode; +} +/*----------------------------------------------------------------------- + */ +static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c) +{ + switch(info->portwidth) { + case FLASH_CFI_8BIT: + cword->c = c; + break; + case FLASH_CFI_16BIT: + cword->w = (cword->w << 8) | c; + break; + case FLASH_CFI_32BIT: + cword->l = (cword->l << 8) | c; + } +} + + +/*----------------------------------------------------------------------- + * make a proper sized command based on the port and chip widths + */ +static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf) +{ + int i; + uchar *cp = (uchar *)cmdbuf; + for(i=0; i< info->portwidth; i++) + *cp++ = ((i+1) % info->chipwidth) ? '\0':cmd; +} + +/* + * Write a proper sized command to the correct address + */ +static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd) +{ + + volatile cfiptr_t addr; + cfiword_t cword; + addr.cp = flash_make_addr(info, sect, offset); + flash_make_cmd(info, cmd, &cword); + switch(info->portwidth) { + case FLASH_CFI_8BIT: + *addr.cp = cword.c; + break; + case FLASH_CFI_16BIT: + *addr.wp = cword.w; + break; + case FLASH_CFI_32BIT: + *addr.lp = cword.l; + break; + } +} + +/*----------------------------------------------------------------------- + */ +static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd) +{ + cfiptr_t cptr; + cfiword_t cword; + int retval; + cptr.cp = flash_make_addr(info, sect, offset); + flash_make_cmd(info, cmd, &cword); + switch(info->portwidth) { + case FLASH_CFI_8BIT: + retval = (cptr.cp[0] == cword.c); + break; + case FLASH_CFI_16BIT: + retval = (cptr.wp[0] == cword.w); + break; + case FLASH_CFI_32BIT: + retval = (cptr.lp[0] == cword.l); + break; + default: + retval = 0; + break; + } + return retval; +} +/*----------------------------------------------------------------------- + */ +static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd) +{ + cfiptr_t cptr; + cfiword_t cword; + int retval; + cptr.cp = flash_make_addr(info, sect, offset); + flash_make_cmd(info, cmd, &cword); + switch(info->portwidth) { + case FLASH_CFI_8BIT: + retval = ((cptr.cp[0] & cword.c) == cword.c); + break; + case FLASH_CFI_16BIT: + retval = ((cptr.wp[0] & cword.w) == cword.w); + break; + case FLASH_CFI_32BIT: + retval = ((cptr.lp[0] & cword.l) == cword.l); + break; + default: + retval = 0; + break; + } + return retval; +} + +/*----------------------------------------------------------------------- + * detect if flash is compatible with the Common Flash Interface (CFI) + * http://www.jedec.org/download/search/jesd68.pdf + * +*/ +static int flash_detect_cfi(flash_info_t * info) +{ + + for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT; + info->portwidth <<= 1) { + for(info->chipwidth =FLASH_CFI_BY8; + info->chipwidth <= info->portwidth; + info->chipwidth <<= 1) { + flash_write_cmd(info, 0, 0, FLASH_CMD_RESET); + flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI); + if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') && + flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') && + flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) + return 1; + } + } + return 0; +} +/* + * The following code cannot be run from FLASH! + * + */ +static ulong flash_get_size (ulong base, int banknum) +{ + flash_info_t * info = &flash_info[banknum]; + int i, j; + int sect_cnt; + unsigned long sector; + unsigned long tmp; + int size_ratio; + uchar num_erase_regions; + int erase_region_size; + int erase_region_count; + + info->start[0] = base; + + if(flash_detect_cfi(info)){ + size_ratio = info->portwidth / info->chipwidth; + num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS); +#ifdef DEBUG_FLASH + printf("found %d erase regions\n", num_erase_regions); +#endif + sect_cnt = 0; + sector = base; + for(i = 0 ; i < num_erase_regions; i++) { + if(i > NUM_ERASE_REGIONS) { + printf("%d erase regions found, only %d used\n", + num_erase_regions, NUM_ERASE_REGIONS); + break; + } + tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS); + erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128; + tmp >>= 16; + erase_region_count = (tmp & 0xffff) +1; + for(j = 0; j< erase_region_count; j++) { + info->start[sect_cnt] = sector; + sector += (erase_region_size * size_ratio); + info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT); + sect_cnt++; + } + } + + info->sector_count = sect_cnt; + /* multiply the size by the number of chips */ + info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio; + info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE)); + tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT); + info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT))); + tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT); + info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT))); + tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT); + info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000; + info->flash_id = FLASH_MAN_CFI; + } + + flash_write_cmd(info, 0, 0, FLASH_CMD_RESET); + return(info->size); +} + + +/*----------------------------------------------------------------------- + */ +static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword) +{ + + cfiptr_t ctladdr; + cfiptr_t cptr; + int flag; + + ctladdr.cp = flash_make_addr(info, 0, 0); + cptr.cp = (uchar *)dest; + + + /* Check if Flash is (sufficiently) erased */ + switch(info->portwidth) { + case FLASH_CFI_8BIT: + flag = ((cptr.cp[0] & cword.c) == cword.c); + break; + case FLASH_CFI_16BIT: + flag = ((cptr.wp[0] & cword.w) == cword.w); + break; + case FLASH_CFI_32BIT: + flag = ((cptr.lp[0] & cword.l) == cword.l); + break; + default: + return 2; + } + if(!flag) + return 2; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS); + flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE); + + switch(info->portwidth) { + case FLASH_CFI_8BIT: + cptr.cp[0] = cword.c; + break; + case FLASH_CFI_16BIT: + cptr.wp[0] = cword.w; + break; + case FLASH_CFI_32BIT: + cptr.lp[0] = cword.l; + break; + } + + /* re-enable interrupts if necessary */ + if(flag) + enable_interrupts(); + + return flash_full_status_check(info, 0, info->write_tout, "write"); +} + +#ifdef CFG_FLASH_USE_BUFFER_WRITE + +/* loop through the sectors from the highest address + * when the passed address is greater or equal to the sector address + * we have a match + */ +static int find_sector(flash_info_t *info, ulong addr) +{ + int sector; + for(sector = info->sector_count - 1; sector >= 0; sector--) { + if(addr >= info->start[sector]) + break; + } + return sector; +} + +static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len) +{ + + int sector; + int cnt; + int retcode; + volatile cfiptr_t src; + volatile cfiptr_t dst; + + src.cp = cp; + dst.cp = (uchar *)dest; + sector = find_sector(info, dest); + flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS); + flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER); + if((retcode = flash_status_check(info, sector, info->buffer_write_tout, + "write to buffer")) == ERR_OK) { + switch(info->portwidth) { + case FLASH_CFI_8BIT: + cnt = len; + break; + case FLASH_CFI_16BIT: + cnt = len >> 1; + break; + case FLASH_CFI_32BIT: + cnt = len >> 2; + break; + default: + return ERR_INVAL; + break; + } + flash_write_cmd(info, sector, 0, (uchar)cnt-1); + while(cnt-- > 0) { + switch(info->portwidth) { + case FLASH_CFI_8BIT: + *dst.cp++ = *src.cp++; + break; + case FLASH_CFI_16BIT: + *dst.wp++ = *src.wp++; + break; + case FLASH_CFI_32BIT: + *dst.lp++ = *src.lp++; + break; + default: + return ERR_INVAL; + break; + } + } + flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM); + retcode = flash_full_status_check(info, sector, info->buffer_write_tout, + "buffer write"); + } + flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS); + return retcode; +} +#endif /* CFG_USE_FLASH_BUFFER_WRITE */ diff --git a/board/rpxsuper/rpxsuper.c b/board/rpxsuper/rpxsuper.c new file mode 100644 index 0000000..2c0717e --- /dev/null +++ b/board/rpxsuper/rpxsuper.c @@ -0,0 +1,305 @@ +/* + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> +#include "rpxsuper.h" + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +const iop_conf_t iop_conf_tab[4][32] = { + + /* Port A configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 *ATMTXEN */ + /* PA30 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTCA */ + /* PA29 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTSOC */ + /* PA28 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 *ATMRXEN */ + /* PA27 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRSOC */ + /* PA26 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRCA */ + /* PA25 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[0] */ + /* PA24 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[1] */ + /* PA23 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[2] */ + /* PA22 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[3] */ + /* PA21 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[4] */ + /* PA20 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[5] */ + /* PA19 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[6] */ + /* PA18 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXD[7] */ + /* PA17 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[7] */ + /* PA16 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[6] */ + /* PA15 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[5] */ + /* PA14 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[4] */ + /* PA13 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[3] */ + /* PA12 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[2] */ + /* PA11 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[1] */ + /* PA10 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXD[0] */ + /* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */ + /* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */ + /* PA7 */ { 1, 0, 0, 0, 0, 0 }, /* PA7 */ + /* PA6 */ { 1, 0, 0, 0, 0, 0 }, /* PA6 */ + /* PA5 */ { 1, 0, 0, 0, 0, 0 }, /* PA5 */ + /* PA4 */ { 1, 0, 0, 0, 0, 0 }, /* PA4 */ + /* PA3 */ { 1, 0, 0, 0, 0, 0 }, /* PA3 */ + /* PA2 */ { 1, 0, 0, 0, 0, 0 }, /* PA2 */ + /* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* PA1 */ + /* PA0 */ { 1, 0, 0, 0, 0, 0 } /* PA0 */ + }, + + /* Port B configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ + /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ + /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ + /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ + /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ + /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ + /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ + /* PB17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_DV */ + /* PB16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_ER */ + /* PB15 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TX_ER */ + /* PB14 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TX_EN */ + /* PB13 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII COL */ + /* PB12 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII CRS */ + /* PB11 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[3] */ + /* PB10 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[2] */ + /* PB9 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[1] */ + /* PB8 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[0] */ + /* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */ + /* PB6 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[1] */ + /* PB5 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[2] */ + /* PB4 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[3] */ + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 1, 0, 0, 1, 0, 0 }, /* PC31 */ + /* PC30 */ { 1, 0, 0, 1, 0, 0 }, /* PC30 */ + /* PC29 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */ + /* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* PC28 */ + /* PC27 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[0] */ + /* PC26 */ { 1, 0, 0, 1, 0, 0 }, /* PC26 */ + /* PC25 */ { 1, 0, 0, 1, 0, 0 }, /* PC25 */ + /* PC24 */ { 1, 0, 0, 1, 0, 0 }, /* PC24 */ + /* PC23 */ { 1, 1, 0, 1, 0, 0 }, /* ATMTFCLK */ + /* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* ATMRFCLK */ + /* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */ + /* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */ + /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */ + /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */ + /* PC17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_CLK */ + /* PC16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII TX_CLK */ + /* PC15 */ { 1, 0, 0, 0, 0, 0 }, /* PC15 */ + /* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */ + /* PC13 */ { 1, 0, 0, 1, 0, 0 }, /* PC13 */ + /* PC12 */ { 1, 0, 0, 1, 0, 0 }, /* PC12 */ + /* PC11 */ { 1, 0, 0, 1, 0, 0 }, /* PC11 */ + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDC */ + /* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */ + /* PC8 */ { 1, 0, 0, 1, 0, 0 }, /* PC8 */ + /* PC7 */ { 1, 0, 0, 1, 0, 0 }, /* PC7 */ + /* PC6 */ { 1, 0, 0, 1, 0, 0 }, /* PC6 */ + /* PC5 */ { 1, 0, 0, 1, 0, 0 }, /* PC5 */ + /* PC4 */ { 1, 0, 0, 1, 0, 0 }, /* PC4 */ + /* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* PC3 */ + /* PC2 */ { 1, 0, 0, 1, 0, 1 }, /* ENET FDE */ + /* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* ENET DSQE */ + /* PC0 */ { 1, 0, 0, 1, 0, 0 }, /* ENET LBK */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 EN RxD */ + /* PD30 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 EN TxD */ + /* PD29 */ { 1, 0, 0, 0, 0, 0 }, /* SCC1 EN TENA */ + /* PD28 */ { 1, 0, 0, 0, 0, 0 }, /* PD28 */ + /* PD27 */ { 1, 0, 0, 0, 0, 0 }, /* PD27 */ + /* PD26 */ { 1, 0, 0, 0, 0, 0 }, /* PD26 */ + /* PD25 */ { 1, 0, 0, 0, 0, 0 }, /* PD25 */ + /* PD24 */ { 1, 0, 0, 0, 0, 0 }, /* PD24 */ + /* PD23 */ { 1, 0, 0, 0, 0, 0 }, /* PD23 */ + /* PD22 */ { 1, 0, 0, 0, 0, 0 }, /* PD22 */ + /* PD21 */ { 1, 0, 0, 0, 0, 0 }, /* PD21 */ + /* PD20 */ { 1, 0, 0, 0, 0, 0 }, /* PD20 */ + /* PD19 */ { 1, 0, 0, 0, 0, 0 }, /* PD19 */ + /* PD18 */ { 1, 0, 0, 0, 0, 0 }, /* PD19 */ + /* PD17 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ + /* PD16 */ { 1, 0, 0, 0, 0, 0 }, /* FCC1 ATMTXPRTY */ + /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ + /* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* PD13 */ + /* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* PD12 */ + /* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* PD11 */ + /* PD10 */ { 1, 0, 0, 0, 0, 0 }, /* PD10 */ + /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */ + /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */ + /* PD7 */ { 1, 0, 0, 0, 0, 0 }, /* PD7 */ + /* PD6 */ { 1, 0, 0, 0, 0, 0 }, /* PD6 */ + /* PD5 */ { 1, 0, 0, 0, 0, 0 }, /* PD5 */ + /* PD4 */ { 1, 0, 0, 0, 0, 0 }, /* PD4 */ + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + } +}; + +/* ------------------------------------------------------------------------- */ + +/* + * Setup CS4 to enable the Board Control/Status registers. + * Otherwise the smcs won't work. +*/ +int board_pre_init (void) +{ + volatile t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + memctl->memc_br4 = CFG_BR4_PRELIM; + memctl->memc_or4 = CFG_OR4_PRELIM; + regs->bcsr1 = 0x70; /* to enable terminal no SMC1 */ + regs->bcsr2 = 0x20; /* mut be written to enable writing FLASH */ + return 0; +} + +void +reset_phy(void) +{ + volatile t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE; + regs->bcsr4 = 0xC3; +} + +/* + * Check Board Identity: + */ + +int checkboard(void) +{ + volatile t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE; + printf ("Board: Embedded Planet RPX Super, Revision %d\n", + regs->bcsr0 >> 4); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram(int board_type) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar c = 0, *ramaddr; + ulong psdmr, lsdmr, bcr; + long size = 0; + int i; + + psdmr = CFG_PSDMR; + lsdmr = CFG_LSDMR; + + /* + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): + * + * "At system reset, initialization software must set up the + * programmable parameters in the memory controller banks registers + * (ORx, BRx, P/LSDMR). After all memory parameters are configured, + * system software should execute the following initialization sequence + * for each SDRAM device. + * + * 1. Issue a PRECHARGE-ALL-BANKS command + * 2. Issue eight CBR REFRESH commands + * 3. Issue a MODE-SET command to initialize the mode register + * + * The initial commands are executed by setting P/LSDMR[OP] and + * accessing the SDRAM with a single-byte transaction." + * + * The appropriate BRx/ORx registers have already been set when we + * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE. + */ + + size = CFG_SDRAM0_SIZE; + bcr = immap->im_siu_conf.sc_bcr; + immap->im_siu_conf.sc_bcr = (bcr & ~BCR_EBM); + + memctl->memc_mptpr = CFG_MPTPR; + + ramaddr = (uchar *)(CFG_SDRAM0_BASE); + memctl->memc_psrt = CFG_PSRT; + + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr = c; + + immap->im_siu_conf.sc_bcr = bcr; + +#ifndef CFG_RAMBOOT +/* size += CFG_SDRAM1_SIZE; */ + ramaddr = (uchar *)(CFG_SDRAM1_BASE); + memctl->memc_lsrt = CFG_LSRT; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_PREA; + *ramaddr = c; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_MRW; + *ramaddr = c; + + memctl->memc_lsdmr = lsdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr = c; +#endif + + /* return total ram size */ + return (size * 1024 * 1024); +} diff --git a/board/rsdproto/config.mk b/board/rsdproto/config.mk new file mode 100644 index 0000000..5844ec1 --- /dev/null +++ b/board/rsdproto/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# MBX8xx boards +# + +TEXT_BASE = 0xff000000 +/*TEXT_BASE = 0x00200000 */ diff --git a/board/rsdproto/rsdproto.c b/board/rsdproto/rsdproto.c new file mode 100644 index 0000000..bf4fd53 --- /dev/null +++ b/board/rsdproto/rsdproto.c @@ -0,0 +1,378 @@ +/* + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> +#include <i2c.h> + +/* define to initialise the SDRAM on the local bus */ +#undef INIT_LOCAL_BUS_SDRAM + +/* I2C Bus adresses for PPC & Protocol board */ +#define PPC8260_I2C_ADR 0x30 /*(0)011.0000 */ +#define LM84_PPC_I2C_ADR 0x2A /*(0)010.1010 */ +#define LM84_SHARC_I2C_ADR 0x29 /*(0)010.1001 */ +#define VIRTEX_I2C_ADR 0x25 /*(0)010.0101 */ +#define X24645_PPC_I2C_ADR 0x00 /*(0)00X.XXXX -> be careful ! No other i2c-chip should have an adress beginning with (0)00 !!! */ +#define RS5C372_PPC_I2C_ADR 0x32 /*(0)011.0010 -> this adress is programmed by the manufacturer and cannot be changed !!! */ + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +const iop_conf_t iop_conf_tab[4][32] = { + + /* Port A configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { 0, 0, 0, 0, 0, 0 }, + /* PA30 */ { 0, 0, 0, 0, 0, 0 }, + /* PA29 */ { 0, 0, 0, 0, 0, 0 }, + /* PA28 */ { 0, 0, 0, 0, 0, 0 }, + /* PA27 */ { 0, 0, 0, 0, 0, 0 }, + /* PA26 */ { 0, 0, 0, 0, 0, 0 }, + /* PA25 */ { 0, 0, 0, 0, 0, 0 }, + /* PA24 */ { 0, 0, 0, 0, 0, 0 }, + /* PA23 */ { 0, 0, 0, 0, 0, 0 }, + /* PA22 */ { 0, 0, 0, 0, 0, 0 }, + /* PA21 */ { 0, 0, 0, 0, 0, 0 }, + /* PA20 */ { 0, 0, 0, 0, 0, 0 }, + /* PA19 */ { 0, 0, 0, 0, 0, 0 }, + /* PA18 */ { 0, 0, 0, 0, 0, 0 }, + /* PA17 */ { 0, 0, 0, 0, 0, 0 }, + /* PA16 */ { 0, 0, 0, 0, 0, 0 }, + /* PA15 */ { 0, 0, 0, 0, 0, 0 }, + /* PA14 */ { 0, 0, 0, 0, 0, 0 }, + /* PA13 */ { 0, 0, 0, 0, 0, 0 }, + /* PA12 */ { 0, 0, 0, 0, 0, 0 }, + /* PA11 */ { 0, 0, 0, 0, 0, 0 }, + /* PA10 */ { 0, 0, 0, 0, 0, 0 }, + /* PA9 */ { 0, 0, 0, 0, 0, 0 }, + /* PA8 */ { 0, 0, 0, 0, 0, 0 }, + /* PA7 */ { 0, 0, 0, 0, 0, 0 }, + /* PA6 */ { 0, 0, 0, 0, 0, 0 }, + /* PA5 */ { 0, 0, 0, 0, 0, 0 }, + /* PA4 */ { 0, 0, 0, 0, 0, 0 }, + /* PA3 */ { 0, 0, 0, 0, 0, 0 }, + /* PA2 */ { 0, 0, 0, 0, 0, 0 }, + /* PA1 */ { 0, 0, 0, 0, 0, 0 }, + /* PA0 */ { 0, 0, 0, 0, 0, 0 } + }, + + + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ + /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ + /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ + /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ + /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ + /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ + /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ + /* PB17 */ { 0, 0, 0, 0, 0, 0 }, + /* PB16 */ { 0, 0, 0, 0, 0, 0 }, + /* PB15 */ { 0, 0, 0, 0, 0, 0 }, + /* PB14 */ { 0, 0, 0, 0, 0, 0 }, + /* PB13 */ { 0, 0, 0, 0, 0, 0 }, + /* PB12 */ { 0, 0, 0, 0, 0, 0 }, + /* PB11 */ { 0, 0, 0, 0, 0, 0 }, + /* PB10 */ { 0, 0, 0, 0, 0, 0 }, + /* PB9 */ { 0, 0, 0, 0, 0, 0 }, + /* PB8 */ { 0, 0, 0, 0, 0, 0 }, + /* PB7 */ { 0, 0, 0, 0, 0, 0 }, + /* PB6 */ { 0, 0, 0, 0, 0, 0 }, + /* PB5 */ { 0, 0, 0, 0, 0, 0 }, + /* PB4 */ { 0, 0, 0, 0, 0, 0 }, + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + }, + + + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 0, 0, 0, 0, 0, 0 }, + /* PC30 */ { 0, 0, 0, 0, 0, 0 }, + /* PC29 */ { 0, 0, 0, 0, 0, 0 }, + /* PC28 */ { 0, 0, 0, 0, 0, 0 }, + /* PC27 */ { 0, 0, 0, 0, 0, 0 }, + /* PC26 */ { 0, 0, 0, 0, 0, 0 }, + /* PC25 */ { 0, 0, 0, 0, 0, 0 }, + /* PC24 */ { 0, 0, 0, 0, 0, 0 }, + /* PC23 */ { 0, 0, 0, 0, 0, 0 }, + /* PC22 */ { 0, 0, 0, 0, 0, 0 }, + /* PC21 */ { 0, 0, 0, 0, 0, 0 }, + /* PC20 */ { 0, 0, 0, 0, 0, 0 }, + /* PC19 */ { 1, 1, 0, 0, 0, 0 }, + /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* ETHRXCLK: CLK14 */ + /* PC17 */ { 0, 0, 0, 0, 0, 0 }, /* ETHTXCLK: CLK15 */ + /* PC16 */ { 0, 0, 0, 0, 0, 0 }, + /* PC15 */ { 0, 0, 0, 0, 0, 0 }, + /* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 UART CD/ */ + /* PC13 */ { 0, 0, 0, 0, 0, 0 }, + /* PC12 */ { 0, 0, 0, 0, 0, 0 }, + /* PC11 */ { 0, 0, 0, 0, 0, 0 }, + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* ETHMDC: GP */ + /* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* ETHMDIO: GP */ + /* PC8 */ { 0, 0, 0, 0, 0, 0 }, + /* PC7 */ { 0, 0, 0, 0, 0, 0 }, + /* PC6 */ { 0, 0, 0, 0, 0, 0 }, + /* PC5 */ { 0, 0, 0, 0, 0, 0 }, + /* PC4 */ { 0, 0, 0, 0, 0, 0 }, + /* PC3 */ { 0, 0, 0, 0, 0, 0 }, + /* PC2 */ { 0, 0, 0, 0, 0, 0 }, + /* PC1 */ { 0, 0, 0, 0, 0, 0 }, + /* PC0 */ { 0, 0, 0, 0, 0, 0 } + }, + + + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 UART RxD */ + /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 UART TxD */ + /* PD29 */ { 0, 0, 0, 0, 0, 0 }, + /* PD28 */ { 0, 0, 0, 0, 0, 0 }, + /* PD27 */ { 0, 0, 0, 0, 0, 0 }, + /* PD26 */ { 0, 0, 0, 0, 0, 0 }, + /* PD25 */ { 0, 0, 0, 0, 0, 0 }, + /* PD24 */ { 0, 0, 0, 0, 0, 0 }, + /* PD23 */ { 0, 0, 0, 0, 0, 0 }, + /* PD22 */ { 0, 0, 0, 0, 0, 0 }, + /* PD21 */ { 0, 0, 0, 0, 0, 0 }, + /* PD20 */ { 0, 0, 0, 0, 0, 0 }, + /* PD19 */ { 0, 0, 0, 0, 0, 0 }, + /* PD18 */ { 0, 0, 0, 0, 0, 0 }, + /* PD17 */ { 0, 0, 0, 0, 0, 0 }, + /* PD16 */ { 0, 0, 0, 0, 0, 0 }, + /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ + /* PD13 */ { 0, 0, 0, 0, 0, 0 }, + /* PD12 */ { 0, 0, 0, 0, 0, 0 }, + /* PD11 */ { 0, 0, 0, 0, 0, 0 }, + /* PD10 */ { 0, 0, 0, 0, 0, 0 }, + /* PD9 */ { 0, 0, 0, 0, 0, 0 }, + /* PD8 */ { 0, 0, 0, 0, 0, 0 }, + /* PD7 */ { 0, 0, 0, 0, 0, 0 }, + /* PD6 */ { 0, 0, 0, 0, 0, 0 }, + /* PD5 */ { 0, 0, 0, 0, 0, 0 }, + /* PD4 */ { 0, 0, 0, 0, 0, 0 }, + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + } +}; + +/* ------------------------------------------------------------------------- */ + +struct tm { + unsigned int tm_sec; + unsigned int tm_min; + unsigned int tm_hour; + unsigned int tm_wday; + unsigned int tm_mday; + unsigned int tm_mon; + unsigned int tm_year; +}; + +void read_RS5C372_time (struct tm *timedate) +{ + unsigned char buffer[8]; + +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) + + if (i2c_read (RS5C372_PPC_I2C_ADR, 0, 1, buffer, sizeof (buffer))) { + timedate->tm_sec = BCD_TO_BIN (buffer[0]); + timedate->tm_min = BCD_TO_BIN (buffer[1]); + timedate->tm_hour = BCD_TO_BIN (buffer[2]); + timedate->tm_wday = BCD_TO_BIN (buffer[3]); + timedate->tm_mday = BCD_TO_BIN (buffer[4]); + timedate->tm_mon = BCD_TO_BIN (buffer[5]); + timedate->tm_year = BCD_TO_BIN (buffer[6]) + 2000; + } else { + /*printf("i2c error %02x\n", rc); */ + memset (timedate, 0, sizeof (struct tm)); + } +} + +/* ------------------------------------------------------------------------- */ + +int read_LM84_temp (int address) +{ + unsigned char buffer[8]; + /*int rc;*/ + + if (i2c_read (address, 0, 1, buffer, 1)) { + return (int) buffer[0]; + } else { + /*printf("i2c error %02x\n", rc); */ + return -42; + } +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + struct tm timedate; + unsigned int ppctemp, prottemp; + + puts ("Board: Rohde & Schwarz 8260 Protocol Board\n"); + + /* initialise i2c */ + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + + read_RS5C372_time (&timedate); + printf (" Time: %02d:%02d:%02d\n", + timedate.tm_hour, timedate.tm_min, timedate.tm_sec); + printf (" Date: %02d-%02d-%04d\n", + timedate.tm_mday, timedate.tm_mon, timedate.tm_year); + ppctemp = read_LM84_temp (LM84_PPC_I2C_ADR); + prottemp = read_LM84_temp (LM84_SHARC_I2C_ADR); + printf (" Temp: PPC %d C, Protocol Board %d C\n", + ppctemp, prottemp); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* + * Miscelaneous platform dependent initialisations while still + * running in flash + */ + +int misc_init_f (void) +{ + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + +#ifdef INIT_LOCAL_BUS_SDRAM + volatile uchar *ramaddr8; +#endif + volatile ulong *ramaddr32; + ulong sdmr; + int i; + + /* + * Only initialize SDRAM when running from FLASH. + * When running from RAM, don't touch it. + */ + if ((ulong) initdram & 0xff000000) { + immap->im_siu_conf.sc_ppc_acr = 0x02; + immap->im_siu_conf.sc_ppc_alrh = 0x01267893; + immap->im_siu_conf.sc_ppc_alrl = 0x89ABCDEF; + immap->im_siu_conf.sc_lcl_acr = 0x02; + immap->im_siu_conf.sc_lcl_alrh = 0x01234567; + immap->im_siu_conf.sc_lcl_alrl = 0x89ABCDEF; + /* + * Program local/60x bus Transfer Error Status and Control Regs: + * Disable parity errors + */ + immap->im_siu_conf.sc_tescr1 = 0x00040000; + immap->im_siu_conf.sc_ltescr1 = 0x00040000; + + /* + * Perform Power-Up Initialisation of SDRAM (see 8260 UM, 10.4.2) + * + * The appropriate BRx/ORx registers have already + * been set when we get here (see cpu_init_f). The + * SDRAM can be accessed at the address CFG_SDRAM_BASE. + */ + memctl->memc_mptpr = 0x2000; + memctl->memc_mar = 0x0200; +#ifdef INIT_LOCAL_BUS_SDRAM + /* initialise local bus ram + * + * (using the PSRMR_ definitions is NOT an error here + * - the LSDMR has the same fields as the PSDMR!) + */ + memctl->memc_lsrt = 0x0b; + memctl->memc_lurt = 0x00; + ramaddr = (uchar *) PHYS_SDRAM_LOCAL; + sdmr = CFG_LSDMR & ~(PSDMR_OP_MSK | PSDMR_RFEN | PSDMR_PBI); + memctl->memc_lsdmr = sdmr | PSDMR_OP_PREA; + *ramaddr = 0xff; + for (i = 0; i < 8; i++) { + memctl->memc_lsdmr = sdmr | PSDMR_OP_CBRR; + *ramaddr = 0xff; + } + memctl->memc_lsdmr = sdmr | PSDMR_OP_MRW; + *ramaddr = 0xff; + memctl->memc_lsdmr = CFG_LSDMR | PSDMR_OP_NORM; +#endif + /* initialise 60x bus ram */ + memctl->memc_psrt = 0x0b; + memctl->memc_purt = 0x08; + ramaddr32 = (ulong *) PHYS_SDRAM_60X; + sdmr = CFG_PSDMR & ~(PSDMR_OP_MSK | PSDMR_RFEN | PSDMR_PBI); + memctl->memc_psdmr = sdmr | PSDMR_OP_PREA; + ramaddr32[0] = 0x00ff00ff; + ramaddr32[1] = 0x00ff00ff; + memctl->memc_psdmr = sdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) { + ramaddr32[0] = 0x00ff00ff; + ramaddr32[1] = 0x00ff00ff; + } + memctl->memc_psdmr = sdmr | PSDMR_OP_MRW; + ramaddr32[0] = 0x00ff00ff; + ramaddr32[1] = 0x00ff00ff; + memctl->memc_psdmr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN; + } + + /* return the size of the 60x bus ram */ + return PHYS_SDRAM_60X_SIZE; +} + +/* ------------------------------------------------------------------------- */ + +/* + * Miscelaneous platform dependent initialisations after monitor + * has been relocated into ram + */ + +int misc_init_r (void) +{ + printf ("misc_init_r\n"); + return (0); +} diff --git a/board/sacsng/sacsng.c b/board/sacsng/sacsng.c new file mode 100644 index 0000000..0f0f0e6 --- /dev/null +++ b/board/sacsng/sacsng.c @@ -0,0 +1,801 @@ +/* + * (C) Copyright 2002 + * Custom IDEAS, Inc. <www.cideas.com> + * Gerald Van Baren <vanbaren@cideas.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm/u-boot.h> +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> +/*NO// #include <memtest.h> */ +#include <i2c.h> +#include <spi.h> + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +#include <status_led.h> +#endif + +#include "clkinit.h" +#include "ioconfig.h" /* I/O configuration table */ + +/* + * PBI Page Based Interleaving + * PSDMR_PBI page based interleaving + * 0 bank based interleaving + * External Address Multiplexing (EAMUX) adds a clock to address cycles + * (this can help with marginal board layouts) + * PSDMR_EAMUX adds a clock + * 0 no extra clock + * Buffer Command (BUFCMD) adds a clock to command cycles. + * PSDMR_BUFCMD adds a clock + * 0 no extra clock + */ +#define CONFIG_PBI PSDMR_PBI +#define PESSIMISTIC_SDRAM 0 +#define EAMUX 0 /* EST requires EAMUX */ +#define BUFCMD 0 + +/* + * ADC/DAC Defines: + */ +#define INITIAL_SAMPLE_RATE 10016 /* Initial Daq sample rate */ +#define INITIAL_RIGHT_JUST 0 /* Initial DAC right justification */ +#define INITIAL_MCLK_DIVIDE 0 /* Initial MCLK Divide */ +#define INITIAL_SAMPLE_64X 1 /* Initial 64x clocking mode */ +#define INITIAL_SAMPLE_128X 0 /* Initial 128x clocking mode */ + +/* + * ADC Defines: + */ +#define I2C_ADC_1_ADDR 0x0E /* I2C Address of the ADC #1 */ +#define I2C_ADC_2_ADDR 0x0F /* I2C Address of the ADC #2 */ + +#define ADC_SDATA1_MASK 0x00020000 /* PA14 - CH12SDATA_PU */ +#define ADC_SDATA2_MASK 0x00010000 /* PA15 - CH34SDATA_PU */ + +#define ADC_VREF_CAP 100 /* VREF capacitor in uF */ +#define ADC_INITIAL_DELAY (10 * ADC_VREF_CAP) /* 10 usec per uF, in usec */ +#define ADC_SDATA_DELAY 100 /* ADC SDATA release delay in usec */ +#define ADC_CAL_DELAY (1000000 / INITIAL_SAMPLE_RATE * 4500) + /* Wait at least 4100 LRCLK's */ + +#define ADC_REG1_FRAME_START 0x80 /* Frame start */ +#define ADC_REG1_GROUND_CAL 0x40 /* Ground calibration enable */ +#define ADC_REG1_ANA_MOD_PDOWN 0x20 /* Analog modulator section in power down */ +#define ADC_REG1_DIG_MOD_PDOWN 0x10 /* Digital modulator section in power down */ + +#define ADC_REG2_128x 0x80 /* Oversample at 128x */ +#define ADC_REG2_CAL 0x40 /* System calibration enable */ +#define ADC_REG2_CHANGE_SIGN 0x20 /* Change sign enable */ +#define ADC_REG2_LR_DISABLE 0x10 /* Left/Right output disable */ +#define ADC_REG2_HIGH_PASS_DIS 0x08 /* High pass filter disable */ +#define ADC_REG2_SLAVE_MODE 0x04 /* Slave mode */ +#define ADC_REG2_DFS 0x02 /* Digital format select */ +#define ADC_REG2_MUTE 0x01 /* Mute */ + +#define ADC_REG7_ADDR_ENABLE 0x80 /* Address enable */ +#define ADC_REG7_PEAK_ENABLE 0x40 /* Peak enable */ +#define ADC_REG7_PEAK_UPDATE 0x20 /* Peak update */ +#define ADC_REG7_PEAK_FORMAT 0x10 /* Peak display format */ +#define ADC_REG7_DIG_FILT_PDOWN 0x04 /* Digital filter power down enable */ +#define ADC_REG7_FIR2_IN_EN 0x02 /* External FIR2 input enable */ +#define ADC_REG7_PSYCHO_EN 0x01 /* External pyscho filter input enable */ + +/* + * DAC Defines: + */ + +#define I2C_DAC_ADDR 0x11 /* I2C Address of the DAC */ + +#define DAC_RST_MASK 0x00008000 /* PA16 - DAC_RST* */ +#define DAC_RESET_DELAY 100 /* DAC reset delay in usec */ +#define DAC_INITIAL_DELAY 5000 /* DAC initialization delay in usec */ + +#define DAC_REG1_AMUTE 0x80 /* Auto-mute */ + +#define DAC_REG1_LEFT_JUST_24_BIT (0 << 4) /* Fmt 0: Left justified 24 bit */ +#define DAC_REG1_I2S_24_BIT (1 << 4) /* Fmt 1: I2S up to 24 bit */ +#define DAC_REG1_RIGHT_JUST_16BIT (2 << 4) /* Fmt 2: Right justified 16 bit */ +#define DAC_REG1_RIGHT_JUST_24BIT (3 << 4) /* Fmt 3: Right justified 24 bit */ +#define DAC_REG1_RIGHT_JUST_20BIT (4 << 4) /* Fmt 4: Right justified 20 bit */ +#define DAC_REG1_RIGHT_JUST_18BIT (5 << 4) /* Fmt 5: Right justified 18 bit */ + +#define DAC_REG1_DEM_NO (0 << 2) /* No De-emphasis */ +#define DAC_REG1_DEM_44KHZ (1 << 2) /* 44.1KHz De-emphasis */ +#define DAC_REG1_DEM_48KHZ (2 << 2) /* 48KHz De-emphasis */ +#define DAC_REG1_DEM_32KHZ (3 << 2) /* 32KHz De-emphasis */ + +#define DAC_REG1_SINGLE 0 /* 4- 50KHz sample rate */ +#define DAC_REG1_DOUBLE 1 /* 50-100KHz sample rate */ +#define DAC_REG1_QUAD 2 /* 100-200KHz sample rate */ +#define DAC_REG1_DSD 3 /* Direct Stream Data, DSD */ + +#define DAC_REG5_INVERT_A 0x80 /* Invert channel A */ +#define DAC_REG5_INVERT_B 0x40 /* Invert channel B */ +#define DAC_REG5_I2C_MODE 0x20 /* Control port (I2C) mode */ +#define DAC_REG5_POWER_DOWN 0x10 /* Power down mode */ +#define DAC_REG5_MUTEC_A_B 0x08 /* Mutec A=B */ +#define DAC_REG5_FREEZE 0x04 /* Freeze */ +#define DAC_REG5_MCLK_DIV 0x02 /* MCLK divide by 2 */ +#define DAC_REG5_RESERVED 0x01 /* Reserved */ + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard(void) +{ + printf ("SACSng\n"); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram(int board_type) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar c = 0; + volatile uchar *ramaddr = (uchar *)(CFG_SDRAM_BASE + 0x8); + uint psdmr = CFG_PSDMR; + int i; + uint psrt = 14; /* for no SPD */ + uint chipselects = 1; /* for no SPD */ + uint sdram_size = CFG_SDRAM0_SIZE * 1024 * 1024; /* for no SPD */ + uint or = CFG_OR2_PRELIM; /* for no SPD */ +#ifdef SDRAM_SPD_ADDR + uint data_width; + uint rows; + uint banks; + uint cols; + uint caslatency; + uint width; + uint rowst; + uint sdam; + uint bsma; + uint sda10; + u_char spd_size; + u_char data; + u_char cksum; + int j; +#endif + +#ifdef SDRAM_SPD_ADDR + /* Keep the compiler from complaining about potentially uninitialized vars */ + data_width = chipselects = rows = banks = cols = caslatency = psrt = 0; + + /* + * Read the SDRAM SPD EEPROM via I2C. + */ + i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1); + spd_size = data; + cksum = data; + for(j = 1; j < 64; j++) { /* read only the checksummed bytes */ + /* note: the I2C address autoincrements when alen == 0 */ + i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1); + if(j == 5) chipselects = data & 0x0F; + else if(j == 6) data_width = data; + else if(j == 7) data_width |= data << 8; + else if(j == 3) rows = data & 0x0F; + else if(j == 4) cols = data & 0x0F; + else if(j == 12) { + /* + * Refresh rate: this assumes the prescaler is set to + * approximately 1uSec per tick. + */ + switch(data & 0x7F) { + default: + case 0: psrt = 14 ; /* 15.625uS */ break; + case 1: psrt = 2; /* 3.9uS */ break; + case 2: psrt = 6; /* 7.8uS */ break; + case 3: psrt = 29; /* 31.3uS */ break; + case 4: psrt = 60; /* 62.5uS */ break; + case 5: psrt = 120; /* 125uS */ break; + } + } + else if(j == 17) banks = data; + else if(j == 18) { + caslatency = 3; /* default CL */ +#if(PESSIMISTIC_SDRAM) + if((data & 0x04) != 0) caslatency = 3; + else if((data & 0x02) != 0) caslatency = 2; + else if((data & 0x01) != 0) caslatency = 1; +#else + if((data & 0x01) != 0) caslatency = 1; + else if((data & 0x02) != 0) caslatency = 2; + else if((data & 0x04) != 0) caslatency = 3; +#endif + else { + printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n", + data); + } + } + else if(j == 63) { + if(data != cksum) { + printf ("WARNING: Configuration data checksum failure:" + " is 0x%02x, calculated 0x%02x\n", + data, cksum); + } + } + cksum += data; + } + + /* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */ + if(caslatency < 2) { + printf("CL was %d, forcing to 2\n", caslatency); + caslatency = 2; + } + if(rows > 14) { + printf("This doesn't look good, rows = %d, should be <= 14\n", rows); + rows = 14; + } + if(cols > 11) { + printf("This doesn't look good, columns = %d, should be <= 11\n", cols); + cols = 11; + } + + if((data_width != 64) && (data_width != 72)) + { + printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n", + data_width); + } + width = 3; /* 2^3 = 8 bytes = 64 bits wide */ + /* + * Convert banks into log2(banks) + */ + if (banks == 2) banks = 1; + else if(banks == 4) banks = 2; + else if(banks == 8) banks = 3; + + sdram_size = 1 << (rows + cols + banks + width); + +#if(CONFIG_PBI == 0) /* bank-based interleaving */ + rowst = ((32 - 6) - (rows + cols + width)) * 2; +#else + rowst = 32 - (rows + banks + cols + width); +#endif + + or = ~(sdram_size - 1) | /* SDAM address mask */ + ((banks-1) << 13) | /* banks per device */ + (rowst << 9) | /* rowst */ + ((rows - 9) << 6); /* numr */ + + memctl->memc_or2 = or; + + /* + * SDAM specifies the number of columns that are multiplexed + * (reference AN2165/D), defined to be (columns - 6) for page + * interleave, (columns - 8) for bank interleave. + * + * BSMA is 14 - max(rows, cols). The bank select lines come + * into play above the highest "address" line going into the + * the SDRAM. + */ +#if(CONFIG_PBI == 0) /* bank-based interleaving */ + sdam = cols - 8; + bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); + sda10 = sdam + 2; +#else + sdam = cols - 6; + bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); + sda10 = sdam; +#endif +#if(PESSIMISTIC_SDRAM) + psdmr = (CONFIG_PBI |\ + PSDMR_RFEN |\ + PSDMR_RFRC_16_CLK |\ + PSDMR_PRETOACT_8W |\ + PSDMR_ACTTORW_8W |\ + PSDMR_WRC_4C |\ + PSDMR_EAMUX |\ + PSDMR_BUFCMD) |\ + caslatency |\ + ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \ + (sdam << 24) |\ + (bsma << 21) |\ + (sda10 << 18); +#else + psdmr = (CONFIG_PBI |\ + PSDMR_RFEN |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W | /* 1 for 7E parts (fast PC-133) */ \ + PSDMR_ACTTORW_2W | /* 1 for 7E parts (fast PC-133) */ \ + PSDMR_WRC_1C | /* 1 clock + 7nSec */ + EAMUX |\ + BUFCMD) |\ + caslatency |\ + ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \ + (sdam << 24) |\ + (bsma << 21) |\ + (sda10 << 18); +#endif +#endif + + /* + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): + * + * "At system reset, initialization software must set up the + * programmable parameters in the memory controller banks registers + * (ORx, BRx, P/LSDMR). After all memory parameters are configured, + * system software should execute the following initialization sequence + * for each SDRAM device. + * + * 1. Issue a PRECHARGE-ALL-BANKS command + * 2. Issue eight CBR REFRESH commands + * 3. Issue a MODE-SET command to initialize the mode register + * + * Quote from Micron MT48LC8M16A2 data sheet: + * + * "...the SDRAM requires a 100uS delay prior to issuing any + * command other than a COMMAND INHIBIT or NOP. Starting at some + * point during this 100uS period and continuing at least through + * the end of this period, COMMAND INHIBIT or NOP commands should + * be applied." + * + * "Once the 100uS delay has been satisfied with at least one COMMAND + * INHIBIT or NOP command having been applied, a /PRECHARGE command/ + * should be applied. All banks must then be precharged, thereby + * placing the device in the all banks idle state." + * + * "Once in the idle state, /two/ AUTO REFRESH cycles must be + * performed. After the AUTO REFRESH cycles are complete, the + * SDRAM is ready for mode register programming." + * + * (/emphasis/ mine, gvb) + * + * The way I interpret this, Micron start up sequence is: + * 1. Issue a PRECHARGE-BANK command (initial precharge) + * 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged") + * 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands + * 4. Issue a MODE-SET command to initialize the mode register + * + * -------- + * + * The initial commands are executed by setting P/LSDMR[OP] and + * accessing the SDRAM with a single-byte transaction." + * + * The appropriate BRx/ORx registers have already been set when we + * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE. + */ + + memctl->memc_mptpr = CFG_MPTPR; + memctl->memc_psrt = psrt; + + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr = c; + + /* + * Do it a second time for the second set of chips if the DIMM has + * two chip selects (double sided). + */ + if(chipselects > 1) { + ramaddr += sdram_size; + + memctl->memc_br3 = CFG_BR3_PRELIM + sdram_size; + memctl->memc_or3 = or; + + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr = c; + } + + /* return total ram size */ + return (sdram_size * chipselects); +} + +/*----------------------------------------------------------------------- + * Board Control Functions + */ +void board_poweroff (void) +{ + while (1); /* hang forever */ +} + + +#ifdef CONFIG_MISC_INIT_R +/* ------------------------------------------------------------------------- */ +int misc_init_r(void) +{ + /* + * Note: iop is used by the I2C macros, and iopa by the ADC/DAC initialization. + */ + volatile ioport_t *iopa = ioport_addr((immap_t *)CFG_IMMR, 0 /* port A */); + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, I2C_PORT); + + int reg; /* I2C register value */ + char *ep; /* Environment pointer */ + char str_buf[12] ; /* sprintf output buffer */ + int sample_rate; /* ADC/DAC sample rate */ + int sample_64x; /* Use 64/4 clocking for the ADC/DAC */ + int sample_128x; /* Use 128/4 clocking for the ADC/DAC */ + int right_just; /* Is the data to the DAC right justified? */ + int mclk_divide; /* MCLK Divide */ + + /* + * SACSng custom initialization: + * Start the ADC and DAC clocks, since the Crystal parts do not + * work on the I2C bus until the clocks are running. + */ + + sample_rate = INITIAL_SAMPLE_RATE; + if ((ep = getenv("DaqSampleRate")) != NULL) { + sample_rate = simple_strtol(ep, NULL, 10); + } + + sample_64x = INITIAL_SAMPLE_64X; + sample_128x = INITIAL_SAMPLE_128X; + if ((ep = getenv("Daq64xSampling")) != NULL) { + sample_64x = simple_strtol(ep, NULL, 10); + if (sample_64x) { + sample_128x = 0; + } + else { + sample_128x = 1; + } + } + else { + if ((ep = getenv("Daq128xSampling")) != NULL) { + sample_128x = simple_strtol(ep, NULL, 10); + if (sample_128x) { + sample_64x = 0; + } + else { + sample_64x = 1; + } + } + } + + Daq_Init_Clocks(sample_rate, sample_64x); + sample_rate = Daq_Get_SampleRate(); + Daq_Start_Clocks(sample_rate); + + sprintf(str_buf, "%d", sample_rate); + setenv("DaqSampleRate", str_buf); + + if (sample_64x) { + setenv("Daq64xSampling", "1"); + setenv("Daq128xSampling", NULL); + } + else { + setenv("Daq64xSampling", NULL); + setenv("Daq128xSampling", "1"); + } + + /* Display the ADC/DAC clocking information */ + Daq_Display_Clocks(); + + /* + * Determine the DAC data justification + */ + + right_just = INITIAL_RIGHT_JUST; + if ((ep = getenv("DaqDACRightJustified")) != NULL) { + right_just = simple_strtol(ep, NULL, 10); + } + + sprintf(str_buf, "%d", right_just); + setenv("DaqDACRightJustified", str_buf); + + /* + * Determine the DAC MCLK Divide + */ + + mclk_divide = INITIAL_MCLK_DIVIDE; + if ((ep = getenv("DaqDACMClockDivide")) != NULL) { + mclk_divide = simple_strtol(ep, NULL, 10); + } + + sprintf(str_buf, "%d", mclk_divide); + setenv("DaqDACMClockDivide", str_buf); + + /* + * Initializing the I2C address in the Crystal A/Ds: + * + * 1) Wait for VREF cap to settle (10uSec per uF) + * 2) Release pullup on SDATA + * 3) Write the I2C address to register 6 + * 4) Enable address matching by setting the MSB in register 7 + */ + + printf("Initializing the ADC...\n"); + udelay(ADC_INITIAL_DELAY); /* 10uSec per uF of VREF cap */ + + iopa->pdat &= ~ADC_SDATA1_MASK; /* release SDATA1 */ + udelay(ADC_SDATA_DELAY); /* arbitrary settling time */ + + i2c_reg_write(0x00, 0x06, I2C_ADC_1_ADDR); /* set address */ + i2c_reg_write(I2C_ADC_1_ADDR, 0x07, /* turn on ADDREN */ + ADC_REG7_ADDR_ENABLE); + + i2c_reg_write(I2C_ADC_1_ADDR, 0x02, /* 128x, slave mode, !HPEN */ + (sample_64x ? 0 : ADC_REG2_128x) | + ADC_REG2_HIGH_PASS_DIS | + ADC_REG2_SLAVE_MODE); + + reg = i2c_reg_read(I2C_ADC_1_ADDR, 0x06) & 0x7F; + if(reg != I2C_ADC_1_ADDR) + printf("Init of ADC U10 failed: address is 0x%02X should be 0x%02X\n", + reg, I2C_ADC_1_ADDR); + + iopa->pdat &= ~ADC_SDATA2_MASK; /* release SDATA2 */ + udelay(ADC_SDATA_DELAY); /* arbitrary settling time */ + + i2c_reg_write(0x00, 0x06, I2C_ADC_2_ADDR); /* set address (do not set ADDREN yet) */ + + i2c_reg_write(I2C_ADC_2_ADDR, 0x02, /* 64x, slave mode, !HPEN */ + (sample_64x ? 0 : ADC_REG2_128x) | + ADC_REG2_HIGH_PASS_DIS | + ADC_REG2_SLAVE_MODE); + + reg = i2c_reg_read(I2C_ADC_2_ADDR, 0x06) & 0x7F; + if(reg != I2C_ADC_2_ADDR) + printf("Init of ADC U15 failed: address is 0x%02X should be 0x%02X\n", + reg, I2C_ADC_2_ADDR); + + i2c_reg_write(I2C_ADC_1_ADDR, 0x01, /* set FSTART and GNDCAL */ + ADC_REG1_FRAME_START | + ADC_REG1_GROUND_CAL); + + i2c_reg_write(I2C_ADC_1_ADDR, 0x02, /* Start calibration */ + (sample_64x ? 0 : ADC_REG2_128x) | + ADC_REG2_CAL | + ADC_REG2_HIGH_PASS_DIS | + ADC_REG2_SLAVE_MODE); + + udelay(ADC_CAL_DELAY); /* a minimum of 4100 LRCLKs */ + i2c_reg_write(I2C_ADC_1_ADDR, 0x01, 0x00); /* remove GNDCAL */ + + /* + * Now that we have synchronized the ADC's, enable address + * selection on the second ADC as well as the first. + */ + i2c_reg_write(I2C_ADC_2_ADDR, 0x07, ADC_REG7_ADDR_ENABLE); + + /* + * Initialize the Crystal DAC + * + * Two of the config lines are used for I2C so we have to set them + * to the proper initialization state without inadvertantly + * sending an I2C "start" sequence. When we bring the I2C back to + * the normal state, we send an I2C "stop" sequence. + */ + printf("Initializing the DAC...\n"); + + /* + * Bring the I2C clock and data lines low for initialization + */ + I2C_SCL(0); + I2C_DELAY; + I2C_SDA(0); + I2C_ACTIVE; + I2C_DELAY; + + /* Reset the DAC */ + iopa->pdat &= ~DAC_RST_MASK; + udelay(DAC_RESET_DELAY); + + /* Release the DAC reset */ + iopa->pdat |= DAC_RST_MASK; + udelay(DAC_INITIAL_DELAY); + + /* + * Cause the DAC to: + * Enable control port (I2C mode) + * Going into power down + */ + i2c_reg_write(I2C_DAC_ADDR, 0x05, + DAC_REG5_I2C_MODE | + DAC_REG5_POWER_DOWN); + + /* + * Cause the DAC to: + * Enable control port (I2C mode) + * Going into power down + * . MCLK divide by 1 + * . MCLK divide by 2 + */ + i2c_reg_write(I2C_DAC_ADDR, 0x05, + DAC_REG5_I2C_MODE | + DAC_REG5_POWER_DOWN | + (mclk_divide ? DAC_REG5_MCLK_DIV : 0)); + + /* + * Cause the DAC to: + * Auto-mute disabled + * . Format 0, left justified 24 bits + * . Format 3, right justified 24 bits + * No de-emphasis + * . Single speed mode + * . Double speed mode + */ + i2c_reg_write(I2C_DAC_ADDR, 0x01, + (right_just ? DAC_REG1_RIGHT_JUST_24BIT : + DAC_REG1_LEFT_JUST_24_BIT) | + DAC_REG1_DEM_NO | + (sample_rate >= 50000 ? DAC_REG1_DOUBLE : DAC_REG1_SINGLE)); + + sprintf(str_buf, "%d", + sample_rate >= 50000 ? DAC_REG1_DOUBLE : DAC_REG1_SINGLE); + setenv("DaqDACFunctionalMode", str_buf); + + /* + * Cause the DAC to: + * Enable control port (I2C mode) + * Remove power down + * . MCLK divide by 1 + * . MCLK divide by 2 + */ + i2c_reg_write(I2C_DAC_ADDR, 0x05, + DAC_REG5_I2C_MODE | + (mclk_divide ? DAC_REG5_MCLK_DIV : 0)); + + /* + * Create a I2C stop condition: + * low->high on data while clock is high. + */ + I2C_SCL(1); + I2C_DELAY; + I2C_SDA(1); + I2C_DELAY; + I2C_TRISTATE; + + printf("\n"); + +#ifdef CONFIG_SHOW_BOOT_PROGRESS + /* + * Turn off the RED fail LED now that we are up and running. + */ + status_led_set(STATUS_LED_RED, STATUS_LED_OFF); +#endif + + return 0; +} + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +/* + * Show boot status: flash the LED if something goes wrong, indicating + * that last thing that worked and thus, by implication, what is broken. + * + * This stores the last OK value in RAM so this will not work properly + * before RAM is initialized. Since it is being used for indicating + * boot status (i.e. after RAM is initialized), that is OK. + */ +static void flash_code(uchar number, uchar modulo, uchar digits) +{ + int j; + + /* + * Recursively do upper digits. + */ + if(digits > 1) { + flash_code(number / modulo, modulo, digits - 1); + } + + number = number % modulo; + + /* + * Zero is indicated by one long flash (dash). + */ + if(number == 0) { + status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); + udelay(1000000); + status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); + udelay(200000); + } else { + /* + * Non-zero is indicated by short flashes, one per count. + */ + for(j = 0; j < number; j++) { + status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); + udelay(100000); + status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); + udelay(200000); + } + } + /* + * Inter-digit pause: we've already waited 200 mSec, wait 1 sec total + */ + udelay(700000); +} + +static int last_boot_progress; + +void show_boot_progress (int status) +{ + if(status != -1) { + last_boot_progress = status; + } else { + /* + * Houston, we have a problem. Blink the last OK status which + * indicates where things failed. + */ + status_led_set(STATUS_LED_RED, STATUS_LED_ON); + flash_code(last_boot_progress, 5, 3); + udelay(1000000); + status_led_set(STATUS_LED_RED, STATUS_LED_BLINKING); + } +} +#endif /* CONFIG_SHOW_BOOT_PROGRESS */ + + +/* + * The following are used to control the SPI chip selects for the SPI command. + */ +#if (CONFIG_COMMANDS & CFG_CMD_SPI) + +#define SPI_ADC_CS_MASK 0x00000800 +#define SPI_DAC_CS_MASK 0x00001000 + +void spi_adc_chipsel(int cs) +{ + volatile ioport_t *iopd = ioport_addr((immap_t *)CFG_IMMR, 3 /* port D */); + + if(cs) + iopd->pdat &= ~SPI_ADC_CS_MASK; /* activate the chip select */ + else + iopd->pdat |= SPI_ADC_CS_MASK; /* deactivate the chip select */ +} + +void spi_dac_chipsel(int cs) +{ + volatile ioport_t *iopd = ioport_addr((immap_t *)CFG_IMMR, 3 /* port D */); + + if(cs) + iopd->pdat &= ~SPI_DAC_CS_MASK; /* activate the chip select */ + else + iopd->pdat |= SPI_DAC_CS_MASK; /* deactivate the chip select */ +} + +/* + * The SPI command uses this table of functions for controlling the SPI + * chip selects: it calls the appropriate function to control the SPI + * chip selects. + */ +spi_chipsel_type spi_chipsel[2] = { + spi_adc_chipsel, + spi_dac_chipsel +}; +#endif /* CFG_CMD_SPI */ + +#endif /* CONFIG_MISC_INIT_R */ diff --git a/board/sandpoint/flash.c b/board/sandpoint/flash.c new file mode 100644 index 0000000..572199d --- /dev/null +++ b/board/sandpoint/flash.c @@ -0,0 +1,766 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc824x.h> +#include <asm/processor.h> +#include <asm/pci_io.h> +#include <w83c553f.h> + +#define ROM_CS0_START 0xFF800000 +#define ROM_CS1_START 0xFF000000 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +#if defined(CFG_ENV_IS_IN_FLASH) +# ifndef CFG_ENV_ADDR +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET) +# endif +# ifndef CFG_ENV_SIZE +# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE +# endif +# ifndef CFG_ENV_SECT_SIZE +# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE +# endif +#endif + +/*----------------------------------------------------------------------- + * Functions + */ +static int write_word (flash_info_t *info, ulong dest, ulong data); +#if 0 +static void flash_get_offsets (ulong base, flash_info_t *info); +#endif /* 0 */ + +/*flash command address offsets*/ + +#if 0 +#define ADDR0 (0x555) +#define ADDR1 (0x2AA) +#define ADDR3 (0x001) +#else +#define ADDR0 (0xAAA) +#define ADDR1 (0x555) +#define ADDR3 (0x001) +#endif + +#define FLASH_WORD_SIZE unsigned char + +/*----------------------------------------------------------------------- + */ + +#if 0 +static int byte_parity_odd(unsigned char x) __attribute__ ((const)); +#endif /* 0 */ +static unsigned long flash_id(unsigned char mfct, unsigned char chip) __attribute__ ((const)); + +typedef struct +{ + FLASH_WORD_SIZE extval; + unsigned short intval; +} map_entry; + +#if 0 +static int +byte_parity_odd(unsigned char x) +{ + x ^= x >> 4; + x ^= x >> 2; + x ^= x >> 1; + return (x & 0x1) != 0; +} +#endif /* 0 */ + + + +static unsigned long +flash_id(unsigned char mfct, unsigned char chip) +{ + static const map_entry mfct_map[] = + { + {(FLASH_WORD_SIZE) AMD_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_AMD >> 16)}, + {(FLASH_WORD_SIZE) FUJ_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_FUJ >> 16)}, + {(FLASH_WORD_SIZE) STM_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_STM >> 16)}, + {(FLASH_WORD_SIZE) MT_MANUFACT, (unsigned short) ((unsigned long) FLASH_MAN_MT >> 16)}, + {(FLASH_WORD_SIZE) INTEL_MANUFACT,(unsigned short) ((unsigned long) FLASH_MAN_INTEL >> 16)}, + {(FLASH_WORD_SIZE) INTEL_ALT_MANU,(unsigned short) ((unsigned long) FLASH_MAN_INTEL >> 16)} + }; + + static const map_entry chip_map[] = + { + {AMD_ID_F040B, FLASH_AM040}, + {(FLASH_WORD_SIZE) STM_ID_x800AB, FLASH_STM800AB} + }; + + const map_entry *p; + unsigned long result = FLASH_UNKNOWN; + + /* find chip id */ + for(p = &chip_map[0]; p < &chip_map[sizeof chip_map / sizeof chip_map[0]]; p++) + if(p->extval == chip) + { + result = FLASH_VENDMASK | p->intval; + break; + } + + /* find vendor id */ + for(p = &mfct_map[0]; p < &mfct_map[sizeof mfct_map / sizeof mfct_map[0]]; p++) + if(p->extval == mfct) + { + result &= ~FLASH_VENDMASK; + result |= (unsigned long) p->intval << 16; + break; + } + + return result; +} + + + +unsigned long +flash_init(void) +{ + unsigned long i; + unsigned char j; + static const ulong flash_banks[] = CFG_FLASH_BANKS; + + /* Init: no FLASHes known */ + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) + { + flash_info_t * const pflinfo = &flash_info[i]; + pflinfo->flash_id = FLASH_UNKNOWN; + pflinfo->size = 0; + pflinfo->sector_count = 0; + } + + /* Enable writes to Sandpoint flash */ + { + register unsigned char temp; + CONFIG_READ_BYTE(CFG_WINBOND_ISA_CFG_ADDR + WINBOND_CSCR, temp); + temp &= ~0x20; /* clear BIOSWP bit */ + CONFIG_WRITE_BYTE(CFG_WINBOND_ISA_CFG_ADDR + WINBOND_CSCR, temp); + } + + for(i = 0; i < sizeof flash_banks / sizeof flash_banks[0]; i++) + { + flash_info_t * const pflinfo = &flash_info[i]; + const unsigned long base_address = flash_banks[i]; + volatile FLASH_WORD_SIZE * const flash = (FLASH_WORD_SIZE *) base_address; +#if 0 + volatile FLASH_WORD_SIZE * addr2; +#endif +#if 0 + /* write autoselect sequence */ + flash[0x5555] = 0xaa; + flash[0x2aaa] = 0x55; + flash[0x5555] = 0x90; +#else + flash[0xAAA << (3 * i)] = 0xaa; + flash[0x555 << (3 * i)] = 0x55; + flash[0xAAA << (3 * i)] = 0x90; +#endif + __asm__ __volatile__("sync"); + +#if 0 + pflinfo->flash_id = flash_id(flash[0x0], flash[0x1]); +#else + pflinfo->flash_id = flash_id(flash[0x0], flash[0x2 + 14 * i]); +#endif + + switch(pflinfo->flash_id & FLASH_TYPEMASK) + { + case FLASH_AM040: + pflinfo->size = 0x00080000; + pflinfo->sector_count = 8; + for(j = 0; j < 8; j++) + { + pflinfo->start[j] = base_address + 0x00010000 * j; + pflinfo->protect[j] = flash[(j << 16) | 0x2]; + } + break; + case FLASH_STM800AB: + pflinfo->size = 0x00100000; + pflinfo->sector_count = 19; + pflinfo->start[0] = base_address; + pflinfo->start[1] = base_address + 0x4000; + pflinfo->start[2] = base_address + 0x6000; + pflinfo->start[3] = base_address + 0x8000; + for(j = 1; j < 16; j++) + { + pflinfo->start[j+3] = base_address + 0x00010000 * j; + } +#if 0 + /* check for protected sectors */ + for (j = 0; j < pflinfo->sector_count; j++) { + /* read sector protection at sector address, (A7 .. A0) = 0x02 */ + /* D0 = 1 if protected */ + addr2 = (volatile FLASH_WORD_SIZE *)(pflinfo->start[j]); + if (pflinfo->flash_id & FLASH_MAN_SST) + pflinfo->protect[j] = 0; + else + pflinfo->protect[j] = addr2[2] & 1; + } +#endif + break; + } + /* Protect monitor and environment sectors + */ +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, + &flash_info[0]); +#endif + +#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR) + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, + &flash_info[0]); +#endif + + /* reset device to read mode */ + flash[0x0000] = 0xf0; + __asm__ __volatile__("sync"); + } + + return flash_info[0].size + flash_info[1].size; +} + +#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_MAN_SST) + { + 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 /* 0 */ + +/*----------------------------------------------------------------------- + */ +void +flash_print_info(flash_info_t *info) +{ + static const char unk[] = "Unknown"; + const char *mfct = unk, *type = unk; + unsigned int i; + + if(info->flash_id != FLASH_UNKNOWN) + { + switch(info->flash_id & FLASH_VENDMASK) + { + case FLASH_MAN_AMD: mfct = "AMD"; break; + case FLASH_MAN_FUJ: mfct = "FUJITSU"; break; + case FLASH_MAN_STM: mfct = "STM"; break; + case FLASH_MAN_SST: mfct = "SST"; break; + case FLASH_MAN_BM: mfct = "Bright Microelectonics"; break; + case FLASH_MAN_INTEL: mfct = "Intel"; break; + } + + switch(info->flash_id & FLASH_TYPEMASK) + { + case FLASH_AM040: type = "AM29F040B (512K * 8, uniform sector size)"; break; + case FLASH_AM400B: type = "AM29LV400B (4 Mbit, bottom boot sect)"; break; + case FLASH_AM400T: type = "AM29LV400T (4 Mbit, top boot sector)"; break; + case FLASH_AM800B: type = "AM29LV800B (8 Mbit, bottom boot sect)"; break; + case FLASH_AM800T: type = "AM29LV800T (8 Mbit, top boot sector)"; break; + case FLASH_AM160T: type = "AM29LV160T (16 Mbit, top boot sector)"; break; + case FLASH_AM320B: type = "AM29LV320B (32 Mbit, bottom boot sect)"; break; + case FLASH_AM320T: type = "AM29LV320T (32 Mbit, top boot sector)"; break; + case FLASH_STM800AB: type = "M29W800AB (8 Mbit, bottom boot sect)"; break; + case FLASH_SST800A: type = "SST39LF/VF800 (8 Mbit, uniform sector size)"; break; + case FLASH_SST160A: type = "SST39LF/VF160 (16 Mbit, uniform sector size)"; break; + } + } + + printf( + "\n Brand: %s Type: %s\n" + " Size: %lu KB in %d Sectors\n", + mfct, + type, + info->size >> 10, + info->sector_count + ); + + printf (" Sector Start Addresses:"); + + for (i = 0; i < info->sector_count; i++) + { + unsigned long size; + unsigned int erased; + unsigned long * flash = (unsigned long *) info->start[i]; + + /* + * Check if whole sector is erased + */ + size = + (i != (info->sector_count - 1)) ? + (info->start[i + 1] - info->start[i]) >> 2 : + (info->start[0] + info->size - info->start[i]) >> 2; + + for( + flash = (unsigned long *) info->start[i], erased = 1; + (flash != (unsigned long *) info->start[i] + size) && erased; + flash++ + ) + erased = *flash == ~0x0UL; + + printf( + "%s %08lX %s %s", + (i % 5) ? "" : "\n ", + info->start[i], + erased ? "E" : " ", + info->protect[i] ? "RO" : " " + ); + } + + puts("\n"); + return; +} + +#if 0 + +/* + * The following code cannot be run from FLASH! + */ +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; + + printf("flash_get_size: \n"); + /* Write auto select command: read Manufacturer ID */ + eieio(); + addr2[ADDR0] = (FLASH_WORD_SIZE)0xAA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x55; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x90; + value = addr2[0]; + + switch (value) { + case (FLASH_WORD_SIZE)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (FLASH_WORD_SIZE)FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + case (FLASH_WORD_SIZE)SST_MANUFACT: + info->flash_id = FLASH_MAN_SST; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + printf("recognised manufacturer"); + + value = addr2[ADDR3]; /* device ID */ + debug ("\ndev_code=%x\n", value); + + switch (value) { + case (FLASH_WORD_SIZE)AMD_ID_LV400T: + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV400B: + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV800T: + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV800B: + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV160T: + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV160B: + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (FLASH_WORD_SIZE)SST_ID_xF800A: + info->flash_id += FLASH_SST800A; + info->sector_count = 16; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)SST_ID_xF160A: + info->flash_id += FLASH_SST160A; + info->sector_count = 32; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_F040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + + printf("flash id %lx; sector count %x, size %lx\n", info->flash_id,info->sector_count,info->size); + /* set up sector start address table */ + if (info->flash_id & FLASH_MAN_SST) + { + 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; + } + } + + /* 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_MAN_SST) + info->protect[i] = 0; + else + info->protect[i] = addr2[2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr2 = (FLASH_WORD_SIZE *)info->start[0]; + *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + } + + return (info->size); +} + +#endif + + +int +flash_erase(flash_info_t *info, int s_first, int s_last) +{ + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); + int flag, prot, sect, l_sect; + ulong start, now, last; + unsigned char sh8b; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if ((info->flash_id == FLASH_UNKNOWN) || + (info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP))) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Check the ROM CS */ + if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START)) + sh8b = 3; + else + sh8b = 0; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (FLASH_WORD_SIZE *)(info->start[0] + ( + (info->start[sect] - info->start[0]) << sh8b)); + if (info->flash_id & FLASH_MAN_SST) + { + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */ + udelay(30000); /* wait 30 ms */ + } + else + addr[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */ + l_sect = sect; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (FLASH_WORD_SIZE *)(info->start[0] + ( + (info->start[l_sect] - info->start[0]) << sh8b)); + 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 */ + serial_putc ('.'); + last = now; + } + } + +DONE: + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)info->start[0]; + volatile FLASH_WORD_SIZE *dest2; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data; + ulong start; + int flag; + int i; + unsigned char sh8b; + + /* Check the ROM CS */ + if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START)) + sh8b = 3; + else + sh8b = 0; + + dest2 = (FLASH_WORD_SIZE *)(((dest - info->start[0]) << sh8b) + + info->start[0]); + + /* Check if Flash is (sufficiently) erased */ + if ((*dest2 & (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++) + { + addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00A000A0; + + dest2[i << sh8b] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i << sh8b] & (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/sbc8260/flash.c b/board/sbc8260/flash.c new file mode 100644 index 0000000..ab2bf35 --- /dev/null +++ b/board/sbc8260/flash.c @@ -0,0 +1,392 @@ +/* + * (C) Copyright 2000 + * Marius Groeger <mgroeger@sysgo.de> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Flash Routines for AMD 29F080B devices + * + *-------------------------------------------------------------------- + * 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 <common.h> +#include <mpc8xx.h> + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +/*----------------------------------------------------------------------- + * 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); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size; + int i; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* for now, only support the 4 MB Flash SIMM */ + size = flash_get_size((vu_long *)CFG_FLASH0_BASE, &flash_info[0]); + + /* + * protect monitor and environment sectors + */ + +#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif + +#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR) +# ifndef CFG_ENV_SIZE +# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE +# endif + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, + &flash_info[0]); +#endif + + return /*size*/ (CFG_FLASH0_SIZE * 1024 * 1024); +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch ((info->flash_id >> 16) & 0xff) { + case 0x1: + printf ("AMD "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case AMD_ID_F040B: + printf ("AM29F040B (4 Mbit)\n"); + break; + case AMD_ID_F080B: + printf ("AM29F080B (8 Mbit)\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + vu_long vendor, devid; + ulong base = (ulong)addr; + +/* printf("addr = %08lx\n", (unsigned long)addr); */ + + /* Reset and Write auto select command: read Manufacturer ID */ + addr[0] = 0xf0f0f0f0; + addr[0x0555] = 0xAAAAAAAA; + addr[0x02AA] = 0x55555555; + addr[0x0555] = 0x90909090; + udelay (1000); + + vendor = addr[0]; +/* printf("vendor = %08lx\n", vendor); */ + if (vendor != 0x01010101) { + info->size = 0; + goto out; + } + + devid = addr[1]; +/* printf("devid = %08lx\n", devid); */ + + if ((devid & 0xff) == AMD_ID_F080B) { + info->flash_id = (vendor & 0xff) << 16 | AMD_ID_F080B; + /* we have 16 sectors with 64KB each x 4 */ + info->sector_count = 16; + info->size = 4 * info->sector_count * 64*1024; + } + else { + info->size = 0; + goto out; + } + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* sector base address */ + info->start[i] = base + i * (info->size / info->sector_count); + /* read sector protection at sector address, (A7 .. A0) = 0x02 */ + /* D0 = 1 if protected */ + addr = (volatile unsigned long *)(info->start[i]); + info->protect[i] = addr[2] & 1; + } + + /* reset command */ + addr = (vu_long *)info->start[0]; + +out: + addr[0] = 0xf0f0f0f0; + + return info->size; +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + vu_long *addr = (vu_long*)(info->start[0]); + int flag, prot, sect, l_sect; + ulong start, now, last; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[0x0555] = 0xAAAAAAAA; + addr[0x02AA] = 0x55555555; + addr[0x0555] = 0x80808080; + addr[0x0555] = 0xAAAAAAAA; + addr[0x02AA] = 0x55555555; + udelay (100); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr = (vu_long*)(info->start[sect]); + addr[0] = 0x30303030; + l_sect = sect; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (vu_long*)(info->start[l_sect]); + while ((addr[0] & 0x80808080) != 0x80808080) { + 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 */ + serial_putc ('.'); + last = now; + } + } + + DONE: + /* reset to read mode */ + addr = (volatile unsigned long *)info->start[0]; + addr[0] = 0xF0F0F0F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long*)(info->start[0]); + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*((vu_long *)dest) & data) != data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[0x0555] = 0xAAAAAAAA; + addr[0x02AA] = 0x55555555; + addr[0x0555] = 0xA0A0A0A0; + + *((vu_long *)dest) = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/sbc8260/sbc8260.c b/board/sbc8260/sbc8260.c new file mode 100644 index 0000000..48aefa0 --- /dev/null +++ b/board/sbc8260/sbc8260.c @@ -0,0 +1,289 @@ +/* + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ioports.h> +#include <mpc8260.h> + +/* + * I/O Port configuration table + * + * if conf is 1, then that port pin will be configured at boot time + * according to the five values podr/pdir/ppar/psor/pdat for that entry + */ + +const iop_conf_t iop_conf_tab[4][32] = { + + /* Port A configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */ + /* PA30 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTCA */ + /* PA29 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTSOC */ + /* PA28 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 *ATMRXEN */ + /* PA27 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRSOC */ + /* PA26 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRCA */ + /* PA25 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */ + /* PA24 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */ + /* PA23 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */ + /* PA22 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */ + /* PA21 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */ + /* PA20 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */ + /* PA19 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */ + /* PA18 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */ + /* PA17 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[7] */ + /* PA16 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[6] */ + /* PA15 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[5] */ + /* PA14 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[4] */ + /* PA13 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[3] */ + /* PA12 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[2] */ + /* PA11 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[1] */ + /* PA10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[0] */ + /* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */ + /* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */ + /* PA7 */ { 1, 0, 0, 1, 0, 0 }, /* PA7 */ + /* PA6 */ { 1, 0, 0, 1, 0, 0 }, /* PA6 */ + /* PA5 */ { 1, 0, 0, 1, 0, 0 }, /* PA5 */ + /* PA4 */ { 1, 0, 0, 1, 0, 0 }, /* PA4 */ + /* PA3 */ { 1, 0, 0, 1, 0, 0 }, /* PA3 */ + /* PA2 */ { 1, 0, 0, 1, 0, 0 }, /* PA2 */ + /* PA1 */ { 1, 0, 0, 1, 0, 0 }, /* PA1 */ + /* PA0 */ { 1, 0, 0, 1, 0, 0 } /* PA0 */ + }, + + /* Port B configuration */ + { /* conf ppar psor pdir podr pdat */ + /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */ + /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */ + /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */ + /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */ + /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */ + /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */ + /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */ + /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */ + /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */ + /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */ + /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */ + /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */ + /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */ + /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */ + /* PB17 */ { 1, 0, 0, 1, 0, 0 }, /* PB17 */ + /* PB16 */ { 1, 0, 0, 1, 0, 0 }, /* PB16 */ + /* PB15 */ { 1, 0, 0, 1, 0, 0 }, /* PB15 */ + /* PB14 */ { 1, 0, 0, 1, 0, 0 }, /* PB14 */ + /* PB13 */ { 1, 0, 0, 1, 0, 0 }, /* PB13 */ + /* PB12 */ { 1, 0, 0, 1, 0, 0 }, /* PB12 */ + /* PB11 */ { 1, 0, 0, 1, 0, 0 }, /* PB11 */ + /* PB10 */ { 1, 0, 0, 1, 0, 0 }, /* PB10 */ + /* PB9 */ { 1, 0, 0, 1, 0, 0 }, /* PB9 */ + /* PB8 */ { 1, 0, 0, 1, 0, 0 }, /* PB8 */ + /* PB7 */ { 1, 0, 0, 1, 0, 0 }, /* PB7 */ + /* PB6 */ { 1, 0, 0, 1, 0, 0 }, /* PB6 */ + /* PB5 */ { 1, 0, 0, 1, 0, 0 }, /* PB5 */ + /* PB4 */ { 1, 0, 0, 1, 0, 0 }, /* PB4 */ + /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + }, + + /* Port C */ + { /* conf ppar psor pdir podr pdat */ + /* PC31 */ { 1, 0, 0, 1, 0, 0 }, /* PC31 */ + /* PC30 */ { 1, 0, 0, 1, 0, 0 }, /* PC30 */ + /* PC29 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */ + /* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* PC28 */ + /* PC27 */ { 1, 0, 0, 1, 0, 0 }, /* PC27 */ + /* PC26 */ { 1, 0, 0, 1, 0, 0 }, /* PC26 */ + /* PC25 */ { 1, 0, 0, 1, 0, 0 }, /* PC25 */ + /* PC24 */ { 1, 0, 0, 1, 0, 0 }, /* PC24 */ + /* PC23 */ { 1, 1, 0, 1, 0, 0 }, /* ATMTFCLK */ + /* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* ATMRFCLK */ + /* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */ + /* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */ + /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */ + /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */ + /* PC17 */ { 1, 0, 0, 1, 0, 0 }, /* PC17 */ + /* PC16 */ { 1, 0, 0, 1, 0, 0 }, /* PC16 */ + /* PC15 */ { 1, 0, 0, 1, 0, 0 }, /* PC15 */ + /* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */ + /* PC13 */ { 1, 0, 0, 1, 0, 0 }, /* PC13 */ + /* PC12 */ { 1, 0, 0, 1, 0, 0 }, /* PC12 */ + /* PC11 */ { 1, 0, 0, 1, 0, 0 }, /* PC11 */ + /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDC */ + /* PC9 */ { 1, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */ + /* PC8 */ { 1, 0, 0, 1, 0, 0 }, /* PC8 */ + /* PC7 */ { 1, 0, 0, 1, 0, 0 }, /* PC7 */ + /* PC6 */ { 1, 0, 0, 1, 0, 0 }, /* PC6 */ + /* PC5 */ { 1, 0, 0, 1, 0, 0 }, /* PC5 */ + /* PC4 */ { 1, 0, 0, 1, 0, 0 }, /* PC4 */ + /* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* PC3 */ + /* PC2 */ { 1, 0, 0, 1, 0, 1 }, /* ENET FDE */ + /* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* ENET DSQE */ + /* PC0 */ { 1, 0, 0, 1, 0, 0 }, /* ENET LBK */ + }, + + /* Port D */ + { /* conf ppar psor pdir podr pdat */ + /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */ + /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */ + /* PD29 */ { 1, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */ + /* PD28 */ { 1, 0, 0, 1, 0, 0 }, /* PD28 */ + /* PD27 */ { 1, 0, 0, 1, 0, 0 }, /* PD27 */ + /* PD26 */ { 1, 0, 0, 1, 0, 0 }, /* PD26 */ + /* PD25 */ { 1, 0, 0, 1, 0, 0 }, /* PD25 */ + /* PD24 */ { 1, 0, 0, 1, 0, 0 }, /* PD24 */ + /* PD23 */ { 1, 0, 0, 1, 0, 0 }, /* PD23 */ + /* PD22 */ { 1, 0, 0, 1, 0, 0 }, /* PD22 */ + /* PD21 */ { 1, 0, 0, 1, 0, 0 }, /* PD21 */ + /* PD20 */ { 1, 0, 0, 1, 0, 0 }, /* PD20 */ + /* PD19 */ { 1, 0, 0, 1, 0, 0 }, /* PD19 */ + /* PD18 */ { 1, 0, 0, 1, 0, 0 }, /* PD18 */ + /* PD17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */ + /* PD16 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */ +#if defined(CONFIG_SOFT_I2C) + /* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */ + /* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */ +#else +#if defined(CONFIG_HARD_I2C) + /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ +#else /* normal I/O port pins */ + /* PD15 */ { 1, 0, 0, 1, 0, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 0, 0, 1, 0, 0 }, /* I2C SCL */ +#endif +#endif + /* PD13 */ { 1, 0, 0, 0, 0, 0 }, /* PD13 */ + /* PD12 */ { 1, 0, 0, 0, 0, 0 }, /* PD12 */ + /* PD11 */ { 1, 0, 0, 0, 0, 0 }, /* PD11 */ + /* PD10 */ { 1, 0, 0, 0, 0, 0 }, /* PD10 */ + /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */ + /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */ + /* PD7 */ { 1, 0, 0, 1, 0, 1 }, /* PD7 */ + /* PD6 */ { 1, 0, 0, 1, 0, 1 }, /* PD6 */ + /* PD5 */ { 1, 0, 0, 1, 0, 1 }, /* PD5 */ + /* PD4 */ { 1, 0, 0, 1, 0, 1 }, /* PD4 */ + /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */ + /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */ + } +}; + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + puts ("Board: EST SBC8260\n"); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8260_t *memctl = &immap->im_memctl; + volatile uchar c = 0, *ramaddr = (uchar *) (CFG_SDRAM_BASE + 0x8); + ulong psdmr = CFG_PSDMR; + int i; + + /* + * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): + * + * "At system reset, initialization software must set up the + * programmable parameters in the memory controller banks registers + * (ORx, BRx, P/LSDMR). After all memory parameters are configured, + * system software should execute the following initialization sequence + * for each SDRAM device. + * + * 1. Issue a PRECHARGE-ALL-BANKS command + * 2. Issue eight CBR REFRESH commands + * 3. Issue a MODE-SET command to initialize the mode register + * + * The initial commands are executed by setting P/LSDMR[OP] and + * accessing the SDRAM with a single-byte transaction." + * + * The appropriate BRx/ORx registers have already been set when we + * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE. + */ + + memctl->memc_psrt = CFG_PSRT; + memctl->memc_mptpr = CFG_MPTPR; + + memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; + for (i = 0; i < 8; i++) + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; + *ramaddr = c; + + memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; + *ramaddr = c; + + /* return total ram size */ + return (CFG_SDRAM0_SIZE * 1024 * 1024); +} + +#ifdef CONFIG_MISC_INIT_R +/* ------------------------------------------------------------------------- */ +int misc_init_r (void) +{ +#ifdef CFG_LED_BASE + uchar ds = *(unsigned char *) (CFG_LED_BASE + 1); + uchar ss; + uchar tmp[64]; + int res; + + if ((ds != 0) && (ds != 0xff)) { + res = getenv_r ("ethaddr", tmp, sizeof (tmp)); + if (res > 0) { + ss = ((ds >> 4) & 0x0f); + ss += ss < 0x0a ? '0' : ('a' - 10); + tmp[15] = ss; + + ss = (ds & 0x0f); + ss += ss < 0x0a ? '0' : ('a' - 10); + tmp[16] = ss; + + tmp[17] = '\0'; + setenv ("ethaddr", tmp); + /* set the led to show the address */ + *((unsigned char *) (CFG_LED_BASE + 1)) = ds; + } + } +#endif /* CFG_LED_BASE */ + return (0); +} +#endif /* CONFIG_MISC_INIT_R */ diff --git a/board/shannon/config.mk b/board/shannon/config.mk new file mode 100644 index 0000000..736d3af --- /dev/null +++ b/board/shannon/config.mk @@ -0,0 +1,23 @@ +# +# LART board with SA1100 cpu +# +# see http://www.lart.tudelft.nl/ for more information on LART +# + +# +# Tuxscreen has 4 banks of 4 MB DRAM each +# +# c000'0000 +# c800'0000 +# d000'0000 +# d800'0000 +# +# Linux-Kernel is expected to be at c000'8000, entry c000'8000 +# +# we load ourself to d830'0000, the upper 1 MB of the last (4th) bank +# +# download areas is c800'0000 +# + + +TEXT_BASE = 0xd8300000 diff --git a/board/shannon/memsetup.S b/board/shannon/memsetup.S new file mode 100644 index 0000000..4f0c464 --- /dev/null +++ b/board/shannon/memsetup.S @@ -0,0 +1,94 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* some parameters for the board */ + +MEM_BASE: .long 0xa0000000 +MEM_START: .long 0xc0000000 + +#define MDCNFG 0x00 +#define MDCAS0 0x04 +#define MDCAS1 0x08 +#define MDCAS2 0x0c +#define MSC0 0x10 +#define MSC1 0x14 +#define MECR 0x18 + +mdcas0: .long 0xc71c703f @ cccccccf +mdcas1: .long 0xffc71c71 @ fffffffc +mdcas2: .long 0xffffffff @ ffffffff +mdcnfg: .long 0x0334b21f @ 9326991f +msc0: .long 0xfff84458 @ 42304230 +msc1: .long 0xffffffff @ 20182018 +mecr: .long 0x7fff7fff @ 01000000 + +/* setting up the memory */ + +.globl memsetup +memsetup: + ldr r0, MEM_BASE + + /* Setup the flash memory */ + ldr r1, msc0 + str r1, [r0, #MSC0] + + /* Set up the DRAM */ + + /* MDCAS0 */ + ldr r1, mdcas0 + str r1, [r0, #MDCAS0] + + /* MDCAS1 */ + ldr r1, mdcas1 + str r1, [r0, #MDCAS1] + + /* MDCAS2 */ + ldr r1, mdcas2 + str r1, [r0, #MDCAS2] + + /* MDCNFG */ + ldr r1, mdcnfg + str r1, [r0, #MDCNFG] + + /* Set up PCMCIA space */ + ldr r1, mecr + str r1, [r0, #MECR] + + /* Load something to activate bank */ + ldr r1, MEM_START + +.rept 8 + ldr r0, [r1] +.endr + + /* everything is fine now */ + mov pc, lr + diff --git a/board/siemens/IAD210/config.mk b/board/siemens/IAD210/config.mk new file mode 100644 index 0000000..c30abcb --- /dev/null +++ b/board/siemens/IAD210/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2000 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# (C) Copyright 2000, 2001, 2002 +# 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 +# + +# +# iad210 boards +# + +TEXT_BASE = 0x08000000 +/*TEXT_BASE = 0x00200000 */ diff --git a/board/smdk2400/config.mk b/board/smdk2400/config.mk new file mode 100644 index 0000000..18c412a --- /dev/null +++ b/board/smdk2400/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# +# SAMSUNG board with S3C2400X (ARM920T) CPU +# +# see http://www.samsung.com/ for more information on SAMSUNG +# + +# +# SAMSUNG has 1 bank of 32 MB DRAM +# +# 0C00'0000 to 0E00'0000 +# +# Linux-Kernel is expected to be at 0cf0'0000, entry 0cf0'0000 +# optionally with a ramdisk at 0c80'0000 +# +# we load ourself to 0CF00000 (must be high enough not to be +# overwritten by the uncompessing Linux kernel) +# +# download area is 0C80'0000 +# + + +TEXT_BASE = 0x0CF00000 diff --git a/board/smdk2400/memsetup.S b/board/smdk2400/memsetup.S new file mode 100644 index 0000000..b53e996 --- /dev/null +++ b/board/smdk2400/memsetup.S @@ -0,0 +1,165 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the Samsung development board by + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* some parameters for the board */ + +/* + * + * Taken from linux/arch/arm/boot/compressed/head-s3c2400.S + * + * Copyright (C) 2001 Samsung Electronics by chc, 010406 + * + * S3C2400 specific tweaks. + * + */ + +/* memory controller */ +#define BWSCON 0x14000000 +#define BANKCON3 0x14000010 /* for cs8900, ethernet */ + +/* Bank0 */ +#define B0_Tacs 0x0 /* 0 clk */ +#define B0_Tcos 0x0 /* 0 clk */ +#define B0_Tacc 0x7 /* 14 clk */ +#define B0_Tcoh 0x0 /* 0 clk */ +#define B0_Tah 0x0 /* 0 clk */ +#define B0_Tacp 0x0 +#define B0_PMC 0x0 /* normal */ + +/* Bank1 */ +#define B1_Tacs 0x0 /* 0 clk */ +#define B1_Tcos 0x0 /* 0 clk */ +#define B1_Tacc 0x7 /* 14 clk */ +#define B1_Tcoh 0x0 /* 0 clk */ +#define B1_Tah 0x0 /* 0 clk */ +#define B1_Tacp 0x0 +#define B1_PMC 0x0 /* normal */ + +/* Bank2 */ +#define B2_Tacs 0x0 /* 0 clk */ +#define B2_Tcos 0x0 /* 0 clk */ +#define B2_Tacc 0x7 /* 14 clk */ +#define B2_Tcoh 0x0 /* 0 clk */ +#define B2_Tah 0x0 /* 0 clk */ +#define B2_Tacp 0x0 +#define B2_PMC 0x0 /* normal */ + +/* Bank3 - setup for the cs8900 */ +#define B3_Tacs 0x0 /* 0 clk */ +#define B3_Tcos 0x3 /* 4 clk */ +#define B3_Tacc 0x7 /* 14 clk */ +#define B3_Tcoh 0x1 /* 1 clk */ +#define B3_Tah 0x0 /* 0 clk */ +#define B3_Tacp 0x3 /* 6 clk */ +#define B3_PMC 0x0 /* normal */ + +/* Bank4 */ +#define B4_Tacs 0x0 /* 0 clk */ +#define B4_Tcos 0x0 /* 0 clk */ +#define B4_Tacc 0x7 /* 14 clk */ +#define B4_Tcoh 0x0 /* 0 clk */ +#define B4_Tah 0x0 /* 0 clk */ +#define B4_Tacp 0x0 +#define B4_PMC 0x0 /* normal */ + +/* Bank5 */ +#define B5_Tacs 0x0 /* 0 clk */ +#define B5_Tcos 0x0 /* 0 clk */ +#define B5_Tacc 0x7 /* 14 clk */ +#define B5_Tcoh 0x0 /* 0 clk */ +#define B5_Tah 0x0 /* 0 clk */ +#define B5_Tacp 0x0 +#define B5_PMC 0x0 /* normal */ + +/* Bank6 */ +#define B6_MT 0x3 /* SDRAM */ +#define B6_Trcd 0x1 /* 3clk */ +#define B6_SCAN 0x1 /* 9 bit */ + +/* Bank7 */ +#define B7_MT 0x3 /* SDRAM */ +#define B7_Trcd 0x1 /* 3clk */ +#define B7_SCAN 0x1 /* 9 bit */ + +/* refresh parameter */ +#define REFEN 0x1 /* enable refresh */ +#define TREFMD 0x0 /* CBR(CAS before RAS)/auto refresh */ +#define Trp 0x0 /* 2 clk */ +#define Trc 0x3 /* 7 clk */ +#define Tchr 0x2 /* 3 clk */ + +#define REFCNT 1113 /* period=15.6 us, HCLK=60Mhz, (2048+1-15.6*66) */ + + +_TEXT_BASE: + .word TEXT_BASE + +.globl memsetup +memsetup: + /* memory control configuration */ + /* make r0 relative the current location so that it */ + /* reads SMRDATA out of FLASH rather than memory ! */ + ldr r0, =SMRDATA + ldr r1, _TEXT_BASE + sub r0, r0, r1 + ldr r1, =BWSCON /* Bus Width Status Controller */ + add r2, r0, #52 +0: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r2, r0 + bne 0b + + /* everything is fine now */ + mov pc, lr + + .ltorg +/* the literal pools origin */ + +SMRDATA: + .word 0x2211d114 /* d->Ethernet, BUSWIDTH=32 */ + .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) /* GCS0 */ + .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) /* GCS1 */ + .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) /* GCS2 */ + .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) /* GCS3 */ + .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) /* GCS4 */ + .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) /* GCS5 */ + .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) /* GCS6 */ + .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) /* GCS7 */ + .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) + .word 0x10 /* BUSWIDTH=32, SCLK power saving mode, BANKSIZE 32M/32M */ + .word 0x30 /* MRSR6, CL=3clk */ + .word 0x30 /* MRSR7 */ + diff --git a/board/smdk2410/config.mk b/board/smdk2410/config.mk new file mode 100644 index 0000000..b06b493 --- /dev/null +++ b/board/smdk2410/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> +# +# SAMSUNG SMDK2410 board with S3C2410X (ARM920T) cpu +# +# see http://www.samsung.com/ for more information on SAMSUNG +# + +# +# SMDK2410 has 1 bank of 64 MB DRAM +# +# 3000'0000 to 3400'0000 +# +# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000 +# optionally with a ramdisk at 3080'0000 +# +# we load ourself to 33F0'0000 +# +# download area is 3300'0000 +# + + +TEXT_BASE = 0x33F00000 diff --git a/board/trab/config.mk b/board/trab/config.mk new file mode 100644 index 0000000..37ed5b1 --- /dev/null +++ b/board/trab/config.mk @@ -0,0 +1,23 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# +# TRAB board with S3C2400X (arm920t) cpu +# +# see http://www.samsung.com/ for more information on SAMSUNG +# + +# +# TRAB has 1 bank of 16 MB DRAM +# +# 0c00'0000 to 0e00'0000 +# +# Linux-Kernel is expected to be at 0c00'8000, entry 0c00'8000 +# +# we load ourself to 0cf0'0000 +# +# download areas is 0c80'0000 +# + + +TEXT_BASE = 0x0cf00000 diff --git a/board/trab/memsetup.S b/board/trab/memsetup.S new file mode 100644 index 0000000..ea4bccc --- /dev/null +++ b/board/trab/memsetup.S @@ -0,0 +1,168 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the TRAB board by + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* some parameters for the board */ + +/* + * + * Copied from linux/arch/arm/boot/compressed/head-s3c2400.S + * + * Copyright (C) 2001 Samsung Electronics by chc, 010406 + * + * TRAB specific tweaks. + * + */ + +/* memory controller */ +#define BWSCON 0x14000000 + +/* Bank0 */ +#define B0_Tacs 0x0 /* 0 clk */ +#define B0_Tcos 0x0 /* 0 clk */ +#define B0_Tacc 0x7 /* 14 clk */ +#define B0_Tcoh 0x0 /* 0 clk */ +#define B0_Tah 0x0 /* 0 clk */ +#define B0_Tacp 0x0 +#define B0_PMC 0x0 /* normal */ + +/* Bank1 - SRAM */ +#define B1_Tacs 0x0 /* 0 clk */ +#define B1_Tcos 0x0 /* 0 clk */ +#define B1_Tacc 0x7 /* 14 clk */ +#define B1_Tcoh 0x0 /* 0 clk */ +#define B1_Tah 0x0 /* 0 clk */ +#define B1_Tacp 0x0 +#define B1_PMC 0x0 /* normal */ + +/* Bank2 - CPLD */ +#define B2_Tacs 0x0 /* 0 clk */ +#define B2_Tcos 0x4 /* 4 clk */ +#define B2_Tacc 0x7 /* 14 clk */ +#define B2_Tcoh 0x4 /* 4 clk */ +#define B2_Tah 0x0 /* 0 clk */ +#define B2_Tacp 0x0 +#define B2_PMC 0x0 /* normal */ + +/* Bank3 - setup for the cs8900 */ +#define B3_Tacs 0x3 /* 4 clk */ +#define B3_Tcos 0x3 /* 4 clk */ +#define B3_Tacc 0x7 /* 14 clk */ +#define B3_Tcoh 0x1 /* 1 clk */ +#define B3_Tah 0x0 /* 0 clk */ +#define B3_Tacp 0x3 /* 6 clk */ +#define B3_PMC 0x0 /* normal */ + +/* Bank4 */ +#define B4_Tacs 0x0 /* 0 clk */ +#define B4_Tcos 0x0 /* 0 clk */ +#define B4_Tacc 0x7 /* 14 clk */ +#define B4_Tcoh 0x0 /* 0 clk */ +#define B4_Tah 0x0 /* 0 clk */ +#define B4_Tacp 0x0 +#define B4_PMC 0x0 /* normal */ + +/* Bank5 */ +#define B5_Tacs 0x0 /* 0 clk */ +#define B5_Tcos 0x0 /* 0 clk */ +#define B5_Tacc 0x7 /* 14 clk */ +#define B5_Tcoh 0x0 /* 0 clk */ +#define B5_Tah 0x0 /* 0 clk */ +#define B5_Tacp 0x0 +#define B5_PMC 0x0 /* normal */ + +/* Bank6 */ +#define B6_MT 0x3 /* SDRAM */ +#define B6_Trcd 0x1 /* 2clk */ +#define B6_SCAN 0x0 /* 8 bit */ + +/* Bank7 */ +#define B7_MT 0x3 /* SDRAM */ +#define B7_Trcd 0x1 /* 2clk */ +#define B7_SCAN 0x0 /* 8 bit */ + +/* refresh parameter */ +#define REFEN 0x1 /* enable refresh */ +#define TREFMD 0x0 /* CBR(CAS before RAS)/auto refresh */ +#define Trp 0x0 /* 2 clk */ +#define Trc 0x3 /* 7 clk */ +#define Tchr 0x2 /* 3 clk */ + +#ifdef CONFIG_TRAB_50MHZ +#define REFCNT 1269 /* period=15.6 us, HCLK=50Mhz, (2048+1-15.6*50) */ +#else +#define REFCNT 1011 /* period=15.6 us, HCLK=66.5Mhz, (2048+1-15.6*66.5) */ +#endif + + +_TEXT_BASE: + .word TEXT_BASE + +.globl memsetup +memsetup: + /* memory control configuration */ + /* make r0 relative the current location so that it */ + /* reads SMRDATA out of FLASH rather than memory ! */ + ldr r0, =SMRDATA + ldr r1, _TEXT_BASE + sub r0, r0, r1 + ldr r1, =BWSCON /* Bus Width Status Controller */ + add r2, r0, #52 +0: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r2, r0 + bne 0b + + /* everything is fine now */ + mov pc, lr + + .ltorg +/* the literal pools origin */ + +SMRDATA: + .word 0x2211d644 /* d->Ethernet, 6->CPLD, 4->SRAM, 4->FLASH */ + .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) /* GCS0 */ + .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) /* GCS1 */ + .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) /* GCS2 */ + .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) /* GCS3 */ + .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) /* GCS4 */ + .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) /* GCS5 */ + .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) /* GCS6 */ + .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) /* GCS7 */ + .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) + .word 0x17 /* BUSWIDTH=32, SCLK power saving mode, BANKSIZE 16M/16M */ + .word 0x30 /* MRSR6, CL=3clk */ + .word 0x30 /* MRSR7 */ + diff --git a/board/utx8245/flash.c b/board/utx8245/flash.c new file mode 100644 index 0000000..947fbc3 --- /dev/null +++ b/board/utx8245/flash.c @@ -0,0 +1,491 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Gregory E. Allen, gallen@arlut.utexas.edu + * Matthew E. Karger, karger@arlut.utexas.edu + * Applied Research Laboratories, The University of Texas at Austin + * + * 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 <common.h> +#include <mpc824x.h> +#include <asm/processor.h> + +#define ROM_CS0_START 0xFF800000 +#define ROM_CS1_START 0xFF000000 + +#if defined(CFG_ENV_IS_IN_FLASH) +# ifndef CFG_ENV_ADDR +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET) +# endif +# ifndef CFG_ENV_SIZE +# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE +# endif +# ifndef CFG_ENV_SECT_SIZE +# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE +# endif +#endif + +#define FLASH_BANK_SIZE 0x200000 +#define MAIN_SECT_SIZE 0x10000 +#define SECT_SIZE_32KB 0x8000 +#define SECT_SIZE_8KB 0x2000 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +static int write_word (flash_info_t *info, ulong dest, ulong data); + +static __inline__ unsigned long get_msr(void) +{ unsigned long msr; + __asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :); + return msr; +} + +static __inline__ void set_msr(unsigned long msr) +{ + __asm__ __volatile__ ("mtmsr %0" : : "r" (msr)); +} + +/*flash command address offsets*/ +#define ADDR0 (0x555) +#define ADDR1 (0xAAA) +#define ADDR3 (0x001) + +#define FLASH_WORD_SIZE unsigned char + +/*---------------------------------------------------------------------*/ +/*#define DEBUG_FLASH 1 */ + +/*---------------------------------------------------------------------*/ + +unsigned long flash_init(void) +{ + int i, j; + ulong size = 0; + unsigned char manuf_id, device_id; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) + { + vu_char *addr = (vu_char *)(CFG_FLASH_BASE + i * FLASH_BANK_SIZE); + + addr[0x555] = 0xAA; /* 3 cycles to read device info. See */ + addr[0x2AA] = 0x55; /* AM29LV116D datasheet for list of */ + addr[0x555] = 0x90; /* available commands. */ + + manuf_id = addr[0]; + device_id = addr[1]; + +#if defined DEBUG_FLASH + printf("manuf_id = %x, device_id = %x\n", manuf_id, device_id); +#endif + + if ( (manuf_id == (uchar)(AMD_MANUFACT)) && + ( device_id == AMD_ID_LV116DT)) + { + flash_info[i].flash_id = ((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) | + (AMD_ID_LV116DT & FLASH_TYPEMASK); + } else { + flash_info[i].flash_id = FLASH_UNKNOWN; + addr[0] = (long)0xFFFFFFFF; + goto Done; + } + +#if defined DEBUG_FLASH + printf ("flash_id = 0x%08lX\n", flash_info[i].flash_id); +#endif + + addr[0] = (long)0xFFFFFFFF; + + flash_info[i].size = FLASH_BANK_SIZE; + flash_info[i].sector_count = CFG_MAX_FLASH_SECT; + memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); + + for (j = 0; j < flash_info[i].sector_count; j++) + { + + if (j < (CFG_MAX_FLASH_SECT - 3) ) + + flash_info[i].start[j] = CFG_FLASH_BASE + i * FLASH_BANK_SIZE + + j * MAIN_SECT_SIZE; + + else if (j == (CFG_MAX_FLASH_SECT - 3) ) + + flash_info[i].start[j] = flash_info[i].start[j-1] + SECT_SIZE_32KB; + + + else + + flash_info[i].start[j] = flash_info[i].start[j-1] + SECT_SIZE_8KB; + + } + + size += flash_info[i].size; + } + + /* Protect monitor and environment sectors + */ +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE, + CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, &flash_info[0]); +#endif + +#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR) + flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); +#endif + +Done: + return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info(flash_info_t *info) +{ + static const char unk[] = "Unknown"; + const char *mfct = unk, *type = unk; + unsigned int i; + + if(info->flash_id != FLASH_UNKNOWN) + { + switch(info->flash_id & FLASH_VENDMASK) + { + case FLASH_MAN_AMD: mfct = "AMD"; break; + case FLASH_MAN_FUJ: mfct = "FUJITSU"; break; + case FLASH_MAN_STM: mfct = "STM"; break; + case FLASH_MAN_SST: mfct = "SST"; break; + case FLASH_MAN_BM: mfct = "Bright Microelectonics"; break; + case FLASH_MAN_INTEL: mfct = "Intel"; break; + } + + switch(info->flash_id & FLASH_TYPEMASK) + { + case FLASH_AM040: type = "AM29F040B (512K * 8, uniform sector size)"; break; + case FLASH_AM400B: type = "AM29LV400B (4 Mbit, bottom boot sect)"; break; + case FLASH_AM400T: type = "AM29LV400T (4 Mbit, top boot sector)"; break; + case FLASH_AM800B: type = "AM29LV800B (8 Mbit, bottom boot sect)"; break; + case FLASH_AM800T: type = "AM29LV800T (8 Mbit, top boot sector)"; break; + case FLASH_AM160T: type = "AM29LV160T (16 Mbit, top boot sector)"; break; + case FLASH_AM320B: type = "AM29LV320B (32 Mbit, bottom boot sect)"; break; + case FLASH_AM320T: type = "AM29LV320T (32 Mbit, top boot sector)"; break; + case FLASH_STM800AB: type = "M29W800AB (8 Mbit, bottom boot sect)"; break; + case FLASH_SST800A: type = "SST39LF/VF800 (8 Mbit, uniform sector size)"; break; + case FLASH_SST160A: type = "SST39LF/VF160 (16 Mbit, uniform sector size)"; break; + } + } + + printf( + "\n Brand: %s Type: %s\n" + " Size: %lu KB in %d Sectors\n", + mfct, + type, + info->size >> 10, + info->sector_count + ); + + printf (" Sector Start Addresses:"); + + for (i = 0; i < info->sector_count; i++) + { + unsigned long size; + unsigned int erased; + unsigned long * flash = (unsigned long *) info->start[i]; + + /* + * Check if whole sector is erased + */ + size = + (i != (info->sector_count - 1)) ? + (info->start[i + 1] - info->start[i]) >> 2 : + (info->start[0] + info->size - info->start[i]) >> 2; + + for( + flash = (unsigned long *) info->start[i], erased = 1; + (flash != (unsigned long *) info->start[i] + size) && erased; + flash++ + ) + erased = *flash == ~0x0UL; + + printf( + "%s %08lX %s %s", + (i % 5) ? "" : "\n ", + info->start[i], + erased ? "E" : " ", + info->protect[i] ? "RO" : " " + ); + } + + puts("\n"); + return; +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); + int flag, prot, sect, l_sect; + ulong start, now, last; + unsigned char sh8b; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if ((info->flash_id == FLASH_UNKNOWN) || + (info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP))) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Check the ROM CS */ + if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START)) + sh8b = 3; + else + sh8b = 0; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) + { + if (info->protect[sect] == 0) + { /* not protected */ + addr = (FLASH_WORD_SIZE *)(info->start[0] + ( + (info->start[sect] - info->start[0]) << sh8b)); + + if (info->flash_id & FLASH_MAN_SST) + { + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */ + udelay(30000); /* wait 30 ms */ + } + + else + addr[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */ + + l_sect = sect; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + + start = get_timer (0); + last = start; + addr = (FLASH_WORD_SIZE *)(info->start[0] + ( + (info->start[l_sect] - info->start[0]) << sh8b)); + 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 */ + serial_putc ('.'); + last = now; + } + } + +DONE: + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)info->start[0]; + volatile FLASH_WORD_SIZE *dest2; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data; + ulong start; + int flag; + int i; + unsigned char sh8b; + + /* Check the ROM CS */ + if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START)) + sh8b = 3; + else + sh8b = 0; + + dest2 = (FLASH_WORD_SIZE *)(((dest - info->start[0]) << sh8b) + + info->start[0]); + + /* Check if Flash is (sufficiently) erased */ + if ((*dest2 & (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++) + { + addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00A000A0; + + dest2[i << sh8b] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i << sh8b] & (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/walnut405/flash.c b/board/walnut405/flash.c new file mode 100644 index 0000000..81f950b --- /dev/null +++ b/board/walnut405/flash.c @@ -0,0 +1,730 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.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); + +#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_WALNUT405 +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned char +#endif + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0, size_b1; + int i; + uint pbcr; + unsigned long base_b0, base_b1; + + /* Init: no FLASHes known */ + for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + } + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0<<20); + } + + /* Only one bank */ + if (CFG_MAX_FLASH_BANKS == 1) + { + /* Setup offsets */ + flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); + + /* Monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, + FLASH_BASE0_PRELIM, + FLASH_BASE0_PRELIM+CFG_MONITOR_LEN-1, + &flash_info[0]); + 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 */ + return (size_b0 + size_b1); +} + + + +/*----------------------------------------------------------------------- + */ +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; + } + } + } +} + +/*----------------------------------------------------------------------- + */ +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; + 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; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + /* + * Check if whole sector is erased + */ + if (i != (info->sector_count-1)) + size = info->start[i+1] - info->start[i]; + else + size = info->start[0] + info->size - info->start[i]; + erased = 1; + flash = (volatile unsigned long *)info->start[i]; + size = size >> 2; /* divide by 4 for longword access */ + for (k=0; k<size; k++) + { + if (*flash++ != 0xffffffff) + { + erased = 0; + break; + } + } + + if ((i % 5) == 0) + printf ("\n "); +#if 0 /* test-only */ + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " +#else + printf (" %08lX%s%s", + info->start[i], + erased ? " E" : " ", + info->protect[i] ? "RO " : " " +#endif + ); + } + printf ("\n"); + return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * 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; + +#ifdef CONFIG_ADCIOP + value = addr2[2]; +#else + value = addr2[0]; +#endif + + switch (value) { + case (FLASH_WORD_SIZE)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (FLASH_WORD_SIZE)FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + case (FLASH_WORD_SIZE)SST_MANUFACT: + info->flash_id = FLASH_MAN_SST; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + +#ifdef CONFIG_ADCIOP + value = addr2[0]; /* device ID */ + /* printf("\ndev_code=%x\n", value); */ +#else + value = addr2[1]; /* device ID */ +#endif + + 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)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; + 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 */ +#ifdef CONFIG_ADCIOP + addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); + info->protect[i] = addr2[4] & 1; +#else + addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) + info->protect[i] = 0; + else + info->protect[i] = addr2[2] & 1; +#endif + } + + /* + * 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 flash_erase (flash_info_t *info, int s_first, int s_last) +{ + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *addr2; + int flag, prot, sect, l_sect; + int i; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr2 = (FLASH_WORD_SIZE *)(info->start[sect]); + printf("Erasing sector %p\n", addr2); /* CLH */ + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */ + for (i=0; i<50; i++) + udelay(1000); /* wait 1 ms */ + } 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 */ + } + l_sect = sect; + /* + * Wait for each sector to complete, it's more + * reliable. According to AMD Spec, you must + * issue all erase commands within a specified + * timeout. This has been seen to fail, especially + * if printf()s are included (for debug)!! + */ + wait_for_DQ7(info, sect); + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + +#if 0 + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + wait_for_DQ7(info, l_sect); + +DONE: +#endif + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + for (; i<4 && cnt>0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t * info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]); + volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data; + ulong start; + int i; + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile FLASH_WORD_SIZE *) dest) & + (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) { + return (2); + } + + for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) { + int flag; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0; + + dest2[i] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & (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/walnut405/init.S b/board/walnut405/init.S new file mode 100644 index 0000000..d141707 --- /dev/null +++ b/board/walnut405/init.S @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------------+ */ +/* */ +/* 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 and SRAM */ +/* Bank 1 - NVRAM/RTC */ +/* Bank 2 - Keyboard/Mouse controller */ +/* Bank 3 - IR controller */ +/* Bank 4 - not used */ +/* Bank 5 - not used */ +/* Bank 6 - not used */ +/* Bank 7 - FPGA registers */ +/*----------------------------------------------------------------------------- */ +#include <ppc4xx.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + + + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + mflr r4 /* save link register */ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + mtlr r4 /* restore link register */ + addi r4,0,14 /* set ctr to 10; used to prefetch */ + mtctr r4 /* 10 cache lines to fit this function */ + /* in cache (gives us 8x10=80 instrctns) */ +..ebcloop: + icbt r0,r3 /* prefetch cache line for addr in r3 */ + addi r3,r3,32 /* move to next cache line */ + bdnz ..ebcloop /* continue for 10 cache lines */ + + /*------------------------------------------------------------------- */ + /* Delay to ensure all accesses to ROM are complete before changing */ + /* bank 0 timings. 200usec should be enough. */ + /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ + /*------------------------------------------------------------------- */ + addis r3,0,0x0 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + /*----------------------------------------------------------------------- */ + /* Memory Bank 0 (Flash and SRAM) 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 + addis r4,0,0xFFF1 /* BAS=0xFFF,BS=0x0(1MB),BU=0x3(R/W), */ + ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ + mtdcr ebccfgd,r4 + + blr + + +/*----------------------------------------------------------------------------- */ +/* Function: sdram_init */ +/* Description: Dummy implementation here - done in C later */ +/*----------------------------------------------------------------------------- */ + .globl sdram_init +sdram_init: + blr diff --git a/common/cmd_boot.c b/common/cmd_boot.c new file mode 100644 index 0000000..93ab10f --- /dev/null +++ b/common/cmd_boot.c @@ -0,0 +1,1103 @@ +/* + * (C) Copyright 2000-2002 + * 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 + */ + +/* + * Boot support + */ +#include <common.h> +#include <command.h> +#include <cmd_boot.h> +#include <cmd_autoscript.h> +#include <s_record.h> +#include <net.h> +#include <syscall.h> + + +#if (CONFIG_COMMANDS & CFG_CMD_LOADS) +static ulong load_serial (ulong offset); +static int read_record (char *buf, ulong len); +# if (CONFIG_COMMANDS & CFG_CMD_SAVES) +static int save_serial (ulong offset, ulong size); +static int write_record (char *buf); +# endif /* CFG_CMD_SAVES */ + +static int do_echo = 1; +#endif /* CFG_CMD_LOADS */ + + +#if (CONFIG_COMMANDS & CFG_CMD_BDI) +static void print_num(const char *, ulong); + +#ifndef CONFIG_ARM /* PowerPC and other */ + +static void print_str(const char *, const char *); + +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + DECLARE_GLOBAL_DATA_PTR; + + int i; + bd_t *bd = gd->bd; + char buf[32]; + +#ifdef DEBUG + print_num ("bd address", (ulong)bd ); +#endif + print_num ("memstart", bd->bi_memstart ); + print_num ("memsize", bd->bi_memsize ); + print_num ("flashstart", bd->bi_flashstart ); + print_num ("flashsize", bd->bi_flashsize ); + print_num ("flashoffset", bd->bi_flashoffset ); + print_num ("sramstart", bd->bi_sramstart ); + print_num ("sramsize", bd->bi_sramsize ); +#if defined(CONFIG_8xx) || defined(CONFIG_8260) + print_num ("immr_base", bd->bi_immr_base ); +#endif + print_num ("bootflags", bd->bi_bootflags ); +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) + print_str ("procfreq", strmhz(buf, bd->bi_procfreq)); + print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq)); +#if defined(CONFIG_405GP) + print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq)); +#endif +#else +#if defined(CONFIG_8260) + print_str ("vco", strmhz(buf, bd->bi_vco)); + print_str ("sccfreq", strmhz(buf, bd->bi_sccfreq)); + print_str ("brgfreq", strmhz(buf, bd->bi_brgfreq)); +#endif + print_str ("intfreq", strmhz(buf, bd->bi_intfreq)); +#if defined(CONFIG_8260) + print_str ("cpmfreq", strmhz(buf, bd->bi_cpmfreq)); +#endif + print_str ("busfreq", strmhz(buf, bd->bi_busfreq)); +#endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */ + printf ("ethaddr ="); + for (i=0; i<6; ++i) { + printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); + } +#ifdef CONFIG_PN62 + printf ("\neth1addr ="); + for (i=0; i<6; ++i) { + printf ("%c%02X", i ? ':' : ' ', bd->bi_enet1addr[i]); + } +#endif /* CONFIG_PN62 */ +#ifdef CONFIG_HERMES + print_str ("ethspeed", strmhz(buf, bd->bi_ethspeed)); +#endif + printf ("\nIP addr = "); print_IPaddr (bd->bi_ip_addr); + printf ("\nbaudrate = %6ld bps\n", bd->bi_baudrate ); + return 0; +} + +#else /* ARM */ + +int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + DECLARE_GLOBAL_DATA_PTR; + + int i; + bd_t *bd = gd->bd; + + print_num ("arch_number", bd->bi_arch_number); + print_num ("env_t", (ulong)bd->bi_env); + print_num ("boot_params", (ulong)bd->bi_boot_params); + + for (i=0; i<CONFIG_NR_DRAM_BANKS; ++i) { + printf ("DRAM:%02d.start = %08lX\n", + i, bd->bi_dram[i].start); + printf ("DRAM:%02d.size = %08lX\n", + i, bd->bi_dram[i].size); + } + + printf ("ethaddr ="); + for (i=0; i<6; ++i) { + printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); + } + printf ("\n" + "ip_addr = "); + print_IPaddr (bd->bi_ip_addr); + printf ("\n" + "baudrate = %d bps\n", bd->bi_baudrate); + + return 0; +} + +#endif /* CONFIG_ARM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +static void print_num(const char *name, ulong value) +{ + printf ("%-12s= 0x%08lX\n", name, value); +} + +#ifndef CONFIG_ARM +static void print_str(const char *name, const char *str) +{ + printf ("%-12s= %6s MHz\n", name, str); +} +#endif /* CONFIG_ARM */ + +#endif /* CFG_CMD_BDI */ + +int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong addr, rc; + int rcode = 0; + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + addr = simple_strtoul(argv[1], NULL, 16); + + printf ("## Starting application at 0x%08lx ...\n", addr); + + /* + * pass address parameter as argv[0] (aka command name), + * and all remaining args + */ + rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]); + if (rc != 0) rcode = 1; + + printf ("## Application terminated, rc = 0x%lx\n", rc); + return rcode; +} + +#if (CONFIG_COMMANDS & CFG_CMD_LOADS) +int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong offset = 0; + ulong addr; + int i; + char *env_echo; + int rcode = 0; +#ifdef CFG_LOADS_BAUD_CHANGE + DECLARE_GLOBAL_DATA_PTR; + int load_baudrate, current_baudrate; + + load_baudrate = current_baudrate = gd->baudrate; +#endif + + if (((env_echo = getenv("loads_echo")) != NULL) && (*env_echo == '1')) { + do_echo = 1; + } else { + do_echo = 0; + } + +#ifdef CFG_LOADS_BAUD_CHANGE + if (argc >= 2) { + offset = simple_strtoul(argv[1], NULL, 16); + } + if (argc == 3) { + load_baudrate = (int)simple_strtoul(argv[2], NULL, 10); + + /* default to current baudrate */ + if (load_baudrate == 0) + load_baudrate = current_baudrate; + } +#else /* ! CFG_LOADS_BAUD_CHANGE */ + if (argc == 2) { + offset = simple_strtoul(argv[1], NULL, 16); + } +#endif /* CFG_LOADS_BAUD_CHANGE */ + +#ifdef CFG_LOADS_BAUD_CHANGE + if (load_baudrate != current_baudrate) { + printf ("## Switch baudrate to %d bps and press ENTER ...\n", + load_baudrate); + udelay(50000); + gd->baudrate = load_baudrate; + serial_setbrg (); + udelay(50000); + for (;;) { + if (getc() == '\r') + break; + } + } +#endif /* CFG_LOADS_BAUD_CHANGE */ + printf ("## Ready for S-Record download ...\n"); + + addr = load_serial (offset); + + /* + * Gather any trailing characters (for instance, the ^D which + * is sent by 'cu' after sending a file), and give the + * box some time (100 * 1 ms) + */ + for (i=0; i<100; ++i) { + if (serial_tstc()) { + (void) serial_getc(); + } + udelay(1000); + } + + if (addr == ~0) { + printf ("## S-Record download aborted\n"); + rcode = 1; + } else { + printf ("## Start Addr = 0x%08lx\n", addr); + load_addr = addr; + } + +#ifdef CFG_LOADS_BAUD_CHANGE + if (load_baudrate != current_baudrate) { + printf ("## Switch baudrate to %d bps and press ESC ...\n", + current_baudrate); + udelay (50000); + gd->baudrate = current_baudrate; + serial_setbrg (); + udelay (50000); + for (;;) { + if (getc() == 0x1B) /* ESC */ + break; + } + } +#endif + return rcode; +} + +static ulong +load_serial (ulong offset) +{ + char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */ + char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */ + int binlen; /* no. of data bytes in S-Rec. */ + int type; /* return code for record type */ + ulong addr; /* load address from S-Record */ + ulong size; /* number of bytes transferred */ + char buf[32]; + ulong store_addr; + ulong start_addr = ~0; + ulong end_addr = 0; + int line_count = 0; + + while (read_record(record, SREC_MAXRECLEN + 1) >= 0) { + type = srec_decode (record, &binlen, &addr, binbuf); + + if (type < 0) { + return (~0); /* Invalid S-Record */ + } + + switch (type) { + case SREC_DATA2: + case SREC_DATA3: + case SREC_DATA4: + store_addr = addr + offset; + if (addr2info(store_addr)) { + int rc; + + rc = flash_write((uchar *)binbuf,store_addr,binlen); + if (rc != 0) { + flash_perror (rc); + return (~0); + } + } else { + memcpy ((char *)(store_addr), binbuf, binlen); + } + if ((store_addr) < start_addr) + start_addr = store_addr; + if ((store_addr + binlen - 1) > end_addr) + end_addr = store_addr + binlen - 1; + break; + case SREC_END2: + case SREC_END3: + case SREC_END4: + udelay (10000); + size = end_addr - start_addr + 1; + printf ("\n" + "## First Load Addr = 0x%08lX\n" + "## Last Load Addr = 0x%08lX\n" + "## Total Size = 0x%08lX = %ld Bytes\n", + start_addr, end_addr, size, size + ); + flush_cache (addr, size); + sprintf(buf, "%lX", size); + setenv("filesize", buf); + return (addr); + case SREC_START: + break; + default: + break; + } + if (!do_echo) { /* print a '.' every 100 lines */ + if ((++line_count % 100) == 0) + putc ('.'); + } + } + + return (~0); /* Download aborted */ +} + +static int +read_record (char *buf, ulong len) +{ + char *p; + char c; + + --len; /* always leave room for terminating '\0' byte */ + + for (p=buf; p < buf+len; ++p) { + c = serial_getc(); /* read character */ + if (do_echo) + serial_putc (c); /* ... and echo it */ + + switch (c) { + case '\r': + case '\n': + *p = '\0'; + return (p - buf); + case '\0': + case 0x03: /* ^C - Control C */ + return (-1); + default: + *p = c; + } + + /* Check for the console hangup (if any different from serial) */ + + if (syscall_tbl[SYSCALL_GETC] != serial_getc) { + if (ctrlc()) { + return (-1); + } + } + } + + /* line too long - truncate */ + *p = '\0'; + return (p - buf); +} + +#if (CONFIG_COMMANDS & CFG_CMD_SAVES) + +int do_save_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong offset = 0; + ulong size = 0; +#ifdef CFG_LOADS_BAUD_CHANGE + DECLARE_GLOBAL_DATA_PTR; + int save_baudrate, current_baudrate; + + save_baudrate = current_baudrate = gd->baudrate; +#endif + + if (argc >= 2) { + offset = simple_strtoul(argv[1], NULL, 16); + } +#ifdef CFG_LOADS_BAUD_CHANGE + if (argc >= 3) { + size = simple_strtoul(argv[2], NULL, 16); + } + if (argc == 4) { + save_baudrate = (int)simple_strtoul(argv[3], NULL, 10); + + /* default to current baudrate */ + if (save_baudrate == 0) + save_baudrate = current_baudrate; + } +#else /* ! CFG_LOADS_BAUD_CHANGE */ + if (argc == 3) { + size = simple_strtoul(argv[2], NULL, 16); + } +#endif /* CFG_LOADS_BAUD_CHANGE */ + +#ifdef CFG_LOADS_BAUD_CHANGE + if (save_baudrate != current_baudrate) { + printf ("## Switch baudrate to %d bps and press ENTER ...\n", + save_baudrate); + udelay(50000); + gd->baudrate = save_baudrate; + serial_setbrg (); + udelay(50000); + for (;;) { + if (getc() == '\r') + break; + } + } +#endif /* CFG_LOADS_BAUD_CHANGE */ + printf ("## Ready for S-Record upload, press ENTER to proceed ...\n"); + for (;;) { + if (getc() == '\r') + break; + } + if(save_serial (offset, size)) { + printf ("## S-Record upload aborted\n"); + } else { + printf ("## S-Record upload complete\n"); + } +#ifdef CFG_LOADS_BAUD_CHANGE + if (save_baudrate != current_baudrate) { + printf ("## Switch baudrate to %d bps and press ESC ...\n", + (int)current_baudrate); + udelay (50000); + gd->baudrate = current_baudrate; + serial_setbrg (); + udelay (50000); + for (;;) { + if (getc() == 0x1B) /* ESC */ + break; + } + } +#endif + return 0; +} + +#define SREC3_START "S0030000FC\n" +#define SREC3_FORMAT "S3%02X%08lX%s%02X\n" +#define SREC3_END "S70500000000FA\n" +#define SREC_BYTES_PER_RECORD 16 + +static int save_serial (ulong address, ulong count) +{ + int i, c, reclen, checksum, length; + char *hex = "0123456789ABCDEF"; + char record[2*SREC_BYTES_PER_RECORD+16]; /* buffer for one S-Record */ + char data[2*SREC_BYTES_PER_RECORD+1]; /* buffer for hex data */ + + reclen = 0; + checksum = 0; + + if(write_record(SREC3_START)) /* write the header */ + return (-1); + do { + if(count) { /* collect hex data in the buffer */ + c = *(volatile uchar*)(address + reclen); /* get one byte */ + checksum += c; /* accumulate checksum */ + data[2*reclen] = hex[(c>>4)&0x0f]; + data[2*reclen+1] = hex[c & 0x0f]; + data[2*reclen+2] = '\0'; + ++reclen; + --count; + } + if(reclen == SREC_BYTES_PER_RECORD || count == 0) { + /* enough data collected for one record: dump it */ + if(reclen) { /* build & write a data record: */ + /* address + data + checksum */ + length = 4 + reclen + 1; + + /* accumulate length bytes into checksum */ + for(i = 0; i < 2; i++) + checksum += (length >> (8*i)) & 0xff; + + /* accumulate address bytes into checksum: */ + for(i = 0; i < 4; i++) + checksum += (address >> (8*i)) & 0xff; + + /* make proper checksum byte: */ + checksum = ~checksum & 0xff; + + /* output one record: */ + sprintf(record, SREC3_FORMAT, length, address, data, checksum); + if(write_record(record)) + return (-1); + } + address += reclen; /* increment address */ + checksum = 0; + reclen = 0; + } + } + while(count); + if(write_record(SREC3_END)) /* write the final record */ + return (-1); + return(0); +} + +static int +write_record (char *buf) +{ + char c; + + while((c = *buf++)) + serial_putc(c); + + /* Check for the console hangup (if any different from serial) */ + + if (ctrlc()) { + return (-1); + } + return (0); +} +# endif /* CFG_CMD_SAVES */ + +#endif /* CFG_CMD_LOADS */ + + +#if (CONFIG_COMMANDS & CFG_CMD_LOADB) /* loadb command (load binary) included */ + +#define XON_CHAR 17 +#define XOFF_CHAR 19 +#define START_CHAR 0x01 +#define END_CHAR 0x0D +#define SPACE 0x20 +#define K_ESCAPE 0x23 +#define SEND_TYPE 'S' +#define DATA_TYPE 'D' +#define ACK_TYPE 'Y' +#define NACK_TYPE 'N' +#define BREAK_TYPE 'B' +#define tochar(x) ((char) (((x) + SPACE) & 0xff)) +#define untochar(x) ((int) (((x) - SPACE) & 0xff)) + +extern int os_data_count; +extern int os_data_header[8]; + +static void set_kerm_bin_mode(unsigned long *); +static int k_recv(void); +static ulong load_serial_bin (ulong offset); + + +char his_eol; /* character he needs at end of packet */ +int his_pad_count; /* number of pad chars he needs */ +char his_pad_char; /* pad chars he needs */ +char his_quote; /* quote chars he'll use */ + +int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + DECLARE_GLOBAL_DATA_PTR; + + ulong offset = 0; + ulong addr; + int i; + int load_baudrate, current_baudrate; + int rcode = 0; + + load_baudrate = current_baudrate = gd->baudrate; + + if (argc >= 2) { + offset = simple_strtoul(argv[1], NULL, 16); + } + if (argc == 3) { + load_baudrate = (int)simple_strtoul(argv[2], NULL, 10); + + /* default to current baudrate */ + if (load_baudrate == 0) + load_baudrate = current_baudrate; + } + + if (load_baudrate != current_baudrate) { + printf ("## Switch baudrate to %d bps and press ENTER ...\n", + load_baudrate); + udelay(50000); + gd->baudrate = load_baudrate; + serial_setbrg (); + udelay(50000); + for (;;) { + if (getc() == '\r') + break; + } + } + printf ("## Ready for binary (kermit) download ...\n"); + + addr = load_serial_bin (offset); + + /* + * Gather any trailing characters (for instance, the ^D which + * is sent by 'cu' after sending a file), and give the + * box some time (100 * 1 ms) + */ + for (i=0; i<100; ++i) { + if (serial_tstc()) { + (void) serial_getc(); + } + udelay(1000); + } + + if (addr == ~0) { + load_addr = 0; + printf ("## Binary (kermit) download aborted\n"); + rcode = 1; + } else { + printf ("## Start Addr = 0x%08lx\n", addr); + load_addr = addr; + } + + if (load_baudrate != current_baudrate) { + printf ("## Switch baudrate to %d bps and press ESC ...\n", + current_baudrate); + udelay (50000); + gd->baudrate = current_baudrate; + serial_setbrg (); + udelay (50000); + for (;;) { + if (getc() == 0x1B) /* ESC */ + break; + } + } + +#ifdef CONFIG_AUTOSCRIPT + if (load_addr) { + char *s; + + if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { + printf("Running autoscript at addr 0x%08lX ...\n", load_addr); + rcode = autoscript (load_addr); + } + } +#endif + return rcode; +} + + +static ulong load_serial_bin (ulong offset) +{ + int size; + char buf[32]; + + set_kerm_bin_mode ((ulong *) offset); + size = k_recv (); + flush_cache (offset, size); + + printf("## Total Size = 0x%08x = %d Bytes\n", size, size); + sprintf(buf, "%X", size); + setenv("filesize", buf); + + return offset; +} + +void send_pad (void) +{ + int count = his_pad_count; + + while (count-- > 0) + serial_putc (his_pad_char); +} + +/* converts escaped kermit char to binary char */ +char ktrans (char in) +{ + if ((in & 0x60) == 0x40) { + return (char) (in & ~0x40); + } else if ((in & 0x7f) == 0x3f) { + return (char) (in | 0x40); + } else + return in; +} + +int chk1 (char *buffer) +{ + int total = 0; + + while (*buffer) { + total += *buffer++; + } + return (int) ((total + ((total >> 6) & 0x03)) & 0x3f); +} + +void s1_sendpacket (char *packet) +{ + send_pad (); + while (*packet) { + serial_putc (*packet++); + } +} + +static char a_b[24]; +void send_ack (int n) +{ + a_b[0] = START_CHAR; + a_b[1] = tochar (3); + a_b[2] = tochar (n); + a_b[3] = ACK_TYPE; + a_b[4] = '\0'; + a_b[4] = tochar (chk1 (&a_b[1])); + a_b[5] = his_eol; + a_b[6] = '\0'; + s1_sendpacket (a_b); +} + +void send_nack (int n) +{ + a_b[0] = START_CHAR; + a_b[1] = tochar (3); + a_b[2] = tochar (n); + a_b[3] = NACK_TYPE; + a_b[4] = '\0'; + a_b[4] = tochar (chk1 (&a_b[1])); + a_b[5] = his_eol; + a_b[6] = '\0'; + s1_sendpacket (a_b); +} + + + +/* os_data_* takes an OS Open image and puts it into memory, and + puts the boot header in an array named os_data_header + + if image is binary, no header is stored in os_data_header. +*/ +void (*os_data_init) (void); +void (*os_data_char) (char new_char); +static int os_data_state, os_data_state_saved; +int os_data_count; +static int os_data_count_saved; +static char *os_data_addr, *os_data_addr_saved; +static char *bin_start_address; +int os_data_header[8]; +static void bin_data_init (void) +{ + os_data_state = 0; + os_data_count = 0; + os_data_addr = bin_start_address; +} +static void os_data_save (void) +{ + os_data_state_saved = os_data_state; + os_data_count_saved = os_data_count; + os_data_addr_saved = os_data_addr; +} +static void os_data_restore (void) +{ + os_data_state = os_data_state_saved; + os_data_count = os_data_count_saved; + os_data_addr = os_data_addr_saved; +} +static void bin_data_char (char new_char) +{ + switch (os_data_state) { + case 0: /* data */ + *os_data_addr++ = new_char; + --os_data_count; + break; + } +} +static void set_kerm_bin_mode (unsigned long *addr) +{ + bin_start_address = (char *) addr; + os_data_init = bin_data_init; + os_data_char = bin_data_char; +} + + +/* k_data_* simply handles the kermit escape translations */ +static int k_data_escape, k_data_escape_saved; +void k_data_init (void) +{ + k_data_escape = 0; + os_data_init (); +} +void k_data_save (void) +{ + k_data_escape_saved = k_data_escape; + os_data_save (); +} +void k_data_restore (void) +{ + k_data_escape = k_data_escape_saved; + os_data_restore (); +} +void k_data_char (char new_char) +{ + if (k_data_escape) { + /* last char was escape - translate this character */ + os_data_char (ktrans (new_char)); + k_data_escape = 0; + } else { + if (new_char == his_quote) { + /* this char is escape - remember */ + k_data_escape = 1; + } else { + /* otherwise send this char as-is */ + os_data_char (new_char); + } + } +} + +#define SEND_DATA_SIZE 20 +char send_parms[SEND_DATA_SIZE]; +char *send_ptr; + +/* handle_send_packet interprits the protocol info and builds and + sends an appropriate ack for what we can do */ +void handle_send_packet (int n) +{ + int length = 3; + int bytes; + + /* initialize some protocol parameters */ + his_eol = END_CHAR; /* default end of line character */ + his_pad_count = 0; + his_pad_char = '\0'; + his_quote = K_ESCAPE; + + /* ignore last character if it filled the buffer */ + if (send_ptr == &send_parms[SEND_DATA_SIZE - 1]) + --send_ptr; + bytes = send_ptr - send_parms; /* how many bytes we'll process */ + do { + if (bytes-- <= 0) + break; + /* handle MAXL - max length */ + /* ignore what he says - most I'll take (here) is 94 */ + a_b[++length] = tochar (94); + if (bytes-- <= 0) + break; + /* handle TIME - time you should wait for my packets */ + /* ignore what he says - don't wait for my ack longer than 1 second */ + a_b[++length] = tochar (1); + if (bytes-- <= 0) + break; + /* handle NPAD - number of pad chars I need */ + /* remember what he says - I need none */ + his_pad_count = untochar (send_parms[2]); + a_b[++length] = tochar (0); + if (bytes-- <= 0) + break; + /* handle PADC - pad chars I need */ + /* remember what he says - I need none */ + his_pad_char = ktrans (send_parms[3]); + a_b[++length] = 0x40; /* He should ignore this */ + if (bytes-- <= 0) + break; + /* handle EOL - end of line he needs */ + /* remember what he says - I need CR */ + his_eol = untochar (send_parms[4]); + a_b[++length] = tochar (END_CHAR); + if (bytes-- <= 0) + break; + /* handle QCTL - quote control char he'll use */ + /* remember what he says - I'll use '#' */ + his_quote = send_parms[5]; + a_b[++length] = '#'; + if (bytes-- <= 0) + break; + /* handle QBIN - 8-th bit prefixing */ + /* ignore what he says - I refuse */ + a_b[++length] = 'N'; + if (bytes-- <= 0) + break; + /* handle CHKT - the clock check type */ + /* ignore what he says - I do type 1 (for now) */ + a_b[++length] = '1'; + if (bytes-- <= 0) + break; + /* handle REPT - the repeat prefix */ + /* ignore what he says - I refuse (for now) */ + a_b[++length] = 'N'; + if (bytes-- <= 0) + break; + /* handle CAPAS - the capabilities mask */ + /* ignore what he says - I only do long packets - I don't do windows */ + a_b[++length] = tochar (2); /* only long packets */ + a_b[++length] = tochar (0); /* no windows */ + a_b[++length] = tochar (94); /* large packet msb */ + a_b[++length] = tochar (94); /* large packet lsb */ + } while (0); + + a_b[0] = START_CHAR; + a_b[1] = tochar (length); + a_b[2] = tochar (n); + a_b[3] = ACK_TYPE; + a_b[++length] = '\0'; + a_b[length] = tochar (chk1 (&a_b[1])); + a_b[++length] = his_eol; + a_b[++length] = '\0'; + s1_sendpacket (a_b); +} + +/* k_recv receives a OS Open image file over kermit line */ +static int k_recv (void) +{ + char new_char; + char k_state, k_state_saved; + int sum; + int done; + int length; + int n, last_n; + int z = 0; + int len_lo, len_hi; + + /* initialize some protocol parameters */ + his_eol = END_CHAR; /* default end of line character */ + his_pad_count = 0; + his_pad_char = '\0'; + his_quote = K_ESCAPE; + + /* initialize the k_recv and k_data state machine */ + done = 0; + k_state = 0; + k_data_init (); + k_state_saved = k_state; + k_data_save (); + n = 0; /* just to get rid of a warning */ + last_n = -1; + + /* expect this "type" sequence (but don't check): + S: send initiate + F: file header + D: data (multiple) + Z: end of file + B: break transmission + */ + + /* enter main loop */ + while (!done) { + /* set the send packet pointer to begining of send packet parms */ + send_ptr = send_parms; + + /* With each packet, start summing the bytes starting with the length. + Save the current sequence number. + Note the type of the packet. + If a character less than SPACE (0x20) is received - error. + */ + +#if 0 + /* OLD CODE, Prior to checking sequence numbers */ + /* first have all state machines save current states */ + k_state_saved = k_state; + k_data_save (); +#endif + + /* get a packet */ + /* wait for the starting character */ + while (serial_getc () != START_CHAR); + /* get length of packet */ + sum = 0; + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + length = untochar (new_char); + /* get sequence number */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + n = untochar (new_char); + --length; + + /* NEW CODE - check sequence numbers for retried packets */ + /* Note - this new code assumes that the sequence number is correctly + * received. Handling an invalid sequence number adds another layer + * of complexity that may not be needed - yet! At this time, I'm hoping + * that I don't need to buffer the incoming data packets and can write + * the data into memory in real time. + */ + if (n == last_n) { + /* same sequence number, restore the previous state */ + k_state = k_state_saved; + k_data_restore (); + } else { + /* new sequence number, checkpoint the download */ + last_n = n; + k_state_saved = k_state; + k_data_save (); + } + /* END NEW CODE */ + + /* get packet type */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + k_state = new_char; + --length; + /* check for extended length */ + if (length == -2) { + /* (length byte was 0, decremented twice) */ + /* get the two length bytes */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + len_hi = untochar (new_char); + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + len_lo = untochar (new_char); + length = len_hi * 95 + len_lo; + /* check header checksum */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f)) + goto packet_error; + sum += new_char & 0xff; +/* --length; */ /* new length includes only data and block check to come */ + } + /* bring in rest of packet */ + while (length > 1) { + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + sum += new_char & 0xff; + --length; + if (k_state == DATA_TYPE) { + /* pass on the data if this is a data packet */ + k_data_char (new_char); + } else if (k_state == SEND_TYPE) { + /* save send pack in buffer as is */ + *send_ptr++ = new_char; + /* if too much data, back off the pointer */ + if (send_ptr >= &send_parms[SEND_DATA_SIZE]) + --send_ptr; + } + } + /* get and validate checksum character */ + new_char = serial_getc (); + if ((new_char & 0xE0) == 0) + goto packet_error; + if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f)) + goto packet_error; + /* get END_CHAR */ + new_char = serial_getc (); + if (new_char != END_CHAR) { + packet_error: + /* restore state machines */ + k_state = k_state_saved; + k_data_restore (); + /* send a negative acknowledge packet in */ + send_nack (n); + } else if (k_state == SEND_TYPE) { + /* crack the protocol parms, build an appropriate ack packet */ + handle_send_packet (n); + } else { + /* send simple acknowledge packet in */ + send_ack (n); + /* quit if end of transmission */ + if (k_state == BREAK_TYPE) + done = 1; + } + ++z; + } + return ((ulong) os_data_addr - (ulong) bin_start_address); +} +#endif /* CFG_CMD_LOADB */ +#if (CONFIG_COMMANDS & CFG_CMD_HWFLOW) +int do_hwflow (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + extern int hwflow_onoff(int); + + if (argc == 2) { + if (strcmp(argv[1], "off") == 0) + hwflow_onoff(-1); + else + if (strcmp(argv[1], "on") == 0) + hwflow_onoff(1); + else + printf("Usage: %s\n", cmdtp->usage); + } + printf("RTS/CTS hardware flow control: %s\n", hwflow_onoff(0) ? "on" : "off"); + return 0; +} +#endif /* CFG_CMD_HWFLOW */ diff --git a/common/hush.c b/common/hush.c new file mode 100644 index 0000000..3cb6fc3 --- /dev/null +++ b/common/hush.c @@ -0,0 +1,3461 @@ +/* vi: set sw=4 ts=4: */ +/* + * sh.c -- a prototype Bourne shell grammar parser + * Intended to follow the original Thompson and Ritchie + * "small and simple is beautiful" philosophy, which + * incidentally is a good match to today's BusyBox. + * + * Copyright (C) 2000,2001 Larry Doolittle <larry@doolittle.boa.org> + * + * Credits: + * The parser routines proper are all original material, first + * written Dec 2000 and Jan 2001 by Larry Doolittle. + * The execution engine, the builtins, and much of the underlying + * support has been adapted from busybox-0.49pre's lash, + * which is Copyright (C) 2000 by Lineo, Inc., and + * written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>. + * That, in turn, is based in part on ladsh.c, by Michael K. Johnson and + * Erik W. Troan, which they placed in the public domain. I don't know + * how much of the Johnson/Troan code has survived the repeated rewrites. + * Other credits: + * simple_itoa() was lifted from boa-0.93.15 + * b_addchr() derived from similar w_addchar function in glibc-2.2 + * setup_redirect(), redirect_opt_num(), and big chunks of main() + * and many builtins derived from contributions by Erik Andersen + * miscellaneous bugfixes from Matt Kraai + * + * There are two big (and related) architecture differences between + * this parser and the lash parser. One is that this version is + * actually designed from the ground up to understand nearly all + * of the Bourne grammar. The second, consequential change is that + * the parser and input reader have been turned inside out. Now, + * the parser is in control, and asks for input as needed. The old + * way had the input reader in control, and it asked for parsing to + * take place as needed. The new way makes it much easier to properly + * handle the recursion implicit in the various substitutions, especially + * across continuation lines. + * + * Bash grammar not implemented: (how many of these were in original sh?) + * $@ (those sure look like weird quoting rules) + * $_ + * ! negation operator for pipes + * &> and >& redirection of stdout+stderr + * Brace Expansion + * Tilde Expansion + * fancy forms of Parameter Expansion + * aliases + * Arithmetic Expansion + * <(list) and >(list) Process Substitution + * reserved words: case, esac, select, function + * Here Documents ( << word ) + * Functions + * Major bugs: + * job handling woefully incomplete and buggy + * reserved word execution woefully incomplete and buggy + * to-do: + * port selected bugfixes from post-0.49 busybox lash - done? + * finish implementing reserved words: for, while, until, do, done + * change { and } from special chars to reserved words + * builtins: break, continue, eval, return, set, trap, ulimit + * test magic exec + * handle children going into background + * clean up recognition of null pipes + * check setting of global_argc and global_argv + * control-C handling, probably with longjmp + * follow IFS rules more precisely, including update semantics + * figure out what to do with backslash-newline + * explain why we use signal instead of sigaction + * propagate syntax errors, die on resource errors? + * continuation lines, both explicit and implicit - done? + * memory leak finding and plugging - done? + * more testing, especially quoting rules and redirection + * document how quoting rules not precisely followed for variable assignments + * maybe change map[] to use 2-bit entries + * (eventually) remove all the printf's + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define __U_BOOT__ +#ifdef __U_BOOT__ +#include <malloc.h> /* malloc, free, realloc*/ +#include <linux/ctype.h> /* isalpha, isdigit */ +#include <common.h> /* readline */ +#include <hush.h> +#include <command.h> /* find_cmd */ +#include <cmd_bootm.h> /* do_bootd */ +#endif +#ifdef CFG_HUSH_PARSER +#ifndef __U_BOOT__ +#include <ctype.h> /* isalpha, isdigit */ +#include <unistd.h> /* getpid */ +#include <stdlib.h> /* getenv, atoi */ +#include <string.h> /* strchr */ +#include <stdio.h> /* popen etc. */ +#include <glob.h> /* glob, of course */ +#include <stdarg.h> /* va_list */ +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> /* should be pretty obvious */ + +#include <sys/stat.h> /* ulimit */ +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> + +/* #include <dmalloc.h> */ +/* #define DEBUG_SHELL */ + +#ifdef BB_VER +#include "busybox.h" +#include "cmdedit.h" +#else +#define applet_name "hush" +#include "standalone.h" +#define hush_main main +#undef BB_FEATURE_SH_FANCY_PROMPT +#endif +#endif +#define SPECIAL_VAR_SYMBOL 03 +#ifndef __U_BOOT__ +#define FLAG_EXIT_FROM_LOOP 1 +#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ +#define FLAG_REPARSING (1 << 2) /* >= 2nd pass */ + +#endif + +#ifdef __U_BOOT__ +#define EXIT_SUCCESS 0 +#define EOF -1 +#define syntax() syntax_err() +#define xstrdup strdup +#define error_msg printf +#else +typedef enum { + REDIRECT_INPUT = 1, + REDIRECT_OVERWRITE = 2, + REDIRECT_APPEND = 3, + REDIRECT_HEREIS = 4, + REDIRECT_IO = 5 +} redir_type; + +/* The descrip member of this structure is only used to make debugging + * output pretty */ +struct {int mode; int default_fd; char *descrip;} redir_table[] = { + { 0, 0, "()" }, + { O_RDONLY, 0, "<" }, + { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" }, + { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" }, + { O_RDONLY, -1, "<<" }, + { O_RDWR, 1, "<>" } +}; +#endif + +typedef enum { + PIPE_SEQ = 1, + PIPE_AND = 2, + PIPE_OR = 3, + PIPE_BG = 4, +} pipe_style; + +/* might eventually control execution */ +typedef enum { + RES_NONE = 0, + RES_IF = 1, + RES_THEN = 2, + RES_ELIF = 3, + RES_ELSE = 4, + RES_FI = 5, + RES_FOR = 6, + RES_WHILE = 7, + RES_UNTIL = 8, + RES_DO = 9, + RES_DONE = 10, + RES_XXXX = 11, + RES_IN = 12, + RES_SNTX = 13 +} reserved_style; +#define FLAG_END (1<<RES_NONE) +#define FLAG_IF (1<<RES_IF) +#define FLAG_THEN (1<<RES_THEN) +#define FLAG_ELIF (1<<RES_ELIF) +#define FLAG_ELSE (1<<RES_ELSE) +#define FLAG_FI (1<<RES_FI) +#define FLAG_FOR (1<<RES_FOR) +#define FLAG_WHILE (1<<RES_WHILE) +#define FLAG_UNTIL (1<<RES_UNTIL) +#define FLAG_DO (1<<RES_DO) +#define FLAG_DONE (1<<RES_DONE) +#define FLAG_IN (1<<RES_IN) +#define FLAG_START (1<<RES_XXXX) + +/* This holds pointers to the various results of parsing */ +struct p_context { + struct child_prog *child; + struct pipe *list_head; + struct pipe *pipe; +#ifndef __U_BOOT__ + struct redir_struct *pending_redirect; +#endif + reserved_style w; + int old_flag; /* for figuring out valid reserved words */ + struct p_context *stack; + int type; /* define type of parser : ";$" common or special symbol */ + /* How about quoting status? */ +}; + +#ifndef __U_BOOT__ +struct redir_struct { + redir_type type; /* type of redirection */ + int fd; /* file descriptor being redirected */ + int dup; /* -1, or file descriptor being duplicated */ + struct redir_struct *next; /* pointer to the next redirect in the list */ + glob_t word; /* *word.gl_pathv is the filename */ +}; +#endif + +struct child_prog { +#ifndef __U_BOOT__ + pid_t pid; /* 0 if exited */ +#endif + char **argv; /* program name and arguments */ +#ifdef __U_BOOT__ + int argc; /* number of program arguments */ +#endif + struct pipe *group; /* if non-NULL, first in group or subshell */ +#ifndef __U_BOOT__ + int subshell; /* flag, non-zero if group must be forked */ + struct redir_struct *redirects; /* I/O redirections */ + glob_t glob_result; /* result of parameter globbing */ + int is_stopped; /* is the program currently running? */ + struct pipe *family; /* pointer back to the child's parent pipe */ +#endif + int sp; /* number of SPECIAL_VAR_SYMBOL */ + int type; +}; + +struct pipe { +#ifndef __U_BOOT__ + int jobid; /* job number */ +#endif + int num_progs; /* total number of programs in job */ +#ifndef __U_BOOT__ + int running_progs; /* number of programs running */ + char *text; /* name of job */ + char *cmdbuf; /* buffer various argv's point into */ + pid_t pgrp; /* process group ID for the job */ +#endif + struct child_prog *progs; /* array of commands in pipe */ + struct pipe *next; /* to track background commands */ +#ifndef __U_BOOT__ + int stopped_progs; /* number of programs alive, but stopped */ + int job_context; /* bitmask defining current context */ +#endif + pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */ + reserved_style r_mode; /* supports if, for, while, until */ +}; + +#ifndef __U_BOOT__ +struct close_me { + int fd; + struct close_me *next; +}; +#endif + +struct variables { + char *name; + char *value; + int flg_export; + int flg_read_only; + struct variables *next; +}; + +/* globals, connect us to the outside world + * the first three support $?, $#, and $1 */ +#ifndef __U_BOOT__ +char **global_argv; +unsigned int global_argc; +#endif +unsigned int last_return_code; +#ifndef __U_BOOT__ +extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */ +#endif + +/* "globals" within this file */ +static char *ifs; +static char map[256]; +#ifndef __U_BOOT__ +static int fake_mode; +static int interactive; +static struct close_me *close_me_head; +static const char *cwd; +static struct pipe *job_list; +static unsigned int last_bg_pid; +static unsigned int last_jobid; +static unsigned int shell_terminal; +static char *PS1; +static char *PS2; +struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; +struct variables *top_vars = &shell_ver; +#else +static int flag_repeat = 0; +static int do_repeat = 0; +static struct variables *top_vars ; +#endif /*__U_BOOT__ */ + +#define B_CHUNK (100) +#define B_NOSPAC 1 + +typedef struct { + char *data; + int length; + int maxlen; + int quote; + int nonnull; +} o_string; +#define NULL_O_STRING {NULL,0,0,0,0} +/* used for initialization: + o_string foo = NULL_O_STRING; */ + +/* I can almost use ordinary FILE *. Is open_memstream() universally + * available? Where is it documented? */ +struct in_str { + const char *p; +#ifndef __U_BOOT__ + char peek_buf[2]; +#endif + int __promptme; + int promptmode; +#ifndef __U_BOOT__ + FILE *file; +#endif + int (*get) (struct in_str *); + int (*peek) (struct in_str *); +}; +#define b_getch(input) ((input)->get(input)) +#define b_peek(input) ((input)->peek(input)) + +#ifndef __U_BOOT__ +#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" + +struct built_in_command { + char *cmd; /* name */ + char *descr; /* description */ + int (*function) (struct child_prog *); /* function ptr */ +}; +#endif + +/* belongs in busybox.h */ +static inline int max(int a, int b) { + return (a>b)?a:b; +} + +/* This should be in utility.c */ +#ifdef DEBUG_SHELL +#ifndef __U_BOOT__ +static void debug_printf(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} +#else +#define debug_printf printf /* U-Boot debug flag */ +#endif +#else +static inline void debug_printf(const char *format, ...) { } +#endif +#define final_printf debug_printf + +#ifdef __U_BOOT__ +static void syntax_err(void) { + printf("syntax error\n"); +} +#else +static void __syntax(char *file, int line) { + error_msg("syntax error %s:%d", file, line); +} +#define syntax() __syntax(__FILE__, __LINE__) +#endif + +#ifdef __U_BOOT__ +static void *xmalloc(size_t size); +static void *xrealloc(void *ptr, size_t size); +#else +/* Index of subroutines: */ +/* function prototypes for builtins */ +static int builtin_cd(struct child_prog *child); +static int builtin_env(struct child_prog *child); +static int builtin_eval(struct child_prog *child); +static int builtin_exec(struct child_prog *child); +static int builtin_exit(struct child_prog *child); +static int builtin_export(struct child_prog *child); +static int builtin_fg_bg(struct child_prog *child); +static int builtin_help(struct child_prog *child); +static int builtin_jobs(struct child_prog *child); +static int builtin_pwd(struct child_prog *child); +static int builtin_read(struct child_prog *child); +static int builtin_set(struct child_prog *child); +static int builtin_shift(struct child_prog *child); +static int builtin_source(struct child_prog *child); +static int builtin_umask(struct child_prog *child); +static int builtin_unset(struct child_prog *child); +static int builtin_not_written(struct child_prog *child); +#endif +/* o_string manipulation: */ +static int b_check_space(o_string *o, int len); +static int b_addchr(o_string *o, int ch); +static void b_reset(o_string *o); +static int b_addqchr(o_string *o, int ch, int quote); +static int b_adduint(o_string *o, unsigned int i); +/* in_str manipulations: */ +static int static_get(struct in_str *i); +static int static_peek(struct in_str *i); +static int file_get(struct in_str *i); +static int file_peek(struct in_str *i); +#ifndef __U_BOOT__ +static void setup_file_in_str(struct in_str *i, FILE *f); +#else +static void setup_file_in_str(struct in_str *i); +#endif +static void setup_string_in_str(struct in_str *i, const char *s); +#ifndef __U_BOOT__ +/* close_me manipulations: */ +static void mark_open(int fd); +static void mark_closed(int fd); +static void close_all(); +#endif +/* "run" the final data structures: */ +static char *indenter(int i); +static int free_pipe_list(struct pipe *head, int indent); +static int free_pipe(struct pipe *pi, int indent); +/* really run the final data structures: */ +#ifndef __U_BOOT__ +static int setup_redirects(struct child_prog *prog, int squirrel[]); +#endif +static int run_list_real(struct pipe *pi); +#ifndef __U_BOOT__ +static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); +#endif +static int run_pipe_real(struct pipe *pi); +/* extended glob support: */ +#ifndef __U_BOOT__ +static int globhack(const char *src, int flags, glob_t *pglob); +static int glob_needed(const char *s); +static int xglob(o_string *dest, int flags, glob_t *pglob); +#endif +/* variable assignment: */ +static int is_assignment(const char *s); +/* data structure manipulation: */ +#ifndef __U_BOOT__ +static int setup_redirect(struct p_context *ctx, int fd, redir_type style, struct in_str *input); +#endif +static void initialize_context(struct p_context *ctx); +static int done_word(o_string *dest, struct p_context *ctx); +static int done_command(struct p_context *ctx); +static int done_pipe(struct p_context *ctx, pipe_style type); +/* primary string parsing: */ +#ifndef __U_BOOT__ +static int redirect_dup_num(struct in_str *input); +static int redirect_opt_num(o_string *o); +static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end); +static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch); +#endif +static char *lookup_param(char *src); +static char *make_string(char **inp); +static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input); +#ifndef __U_BOOT__ +static int parse_string(o_string *dest, struct p_context *ctx, const char *src); +#endif +static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger); +/* setup: */ +static int parse_stream_outer(struct in_str *inp, int flag); +#ifndef __U_BOOT__ +static int parse_string_outer(const char *s, int flag); +static int parse_file_outer(FILE *f); +#endif +#ifndef __U_BOOT__ +/* job management: */ +static int checkjobs(struct pipe* fg_pipe); +static void insert_bg_job(struct pipe *pi); +static void remove_bg_job(struct pipe *pi); +#endif +/* local variable support */ +static char **make_list_in(char **inp, char *name); +static char *insert_var_value(char *inp); +static char *get_local_var(const char *var); +#ifndef __U_BOOT__ +static void unset_local_var(const char *name); +#endif +static int set_local_var(const char *s, int flg_export); + +#ifndef __U_BOOT__ +/* Table of built-in functions. They can be forked or not, depending on + * context: within pipes, they fork. As simple commands, they do not. + * When used in non-forking context, they can change global variables + * in the parent shell process. If forked, of course they can not. + * For example, 'unset foo | whatever' will parse and run, but foo will + * still be set at the end. */ +static struct built_in_command bltins[] = { + {"bg", "Resume a job in the background", builtin_fg_bg}, + {"break", "Exit for, while or until loop", builtin_not_written}, + {"cd", "Change working directory", builtin_cd}, + {"continue", "Continue for, while or until loop", builtin_not_written}, + {"env", "Print all environment variables", builtin_env}, + {"eval", "Construct and run shell command", builtin_eval}, + {"exec", "Exec command, replacing this shell with the exec'd process", + builtin_exec}, + {"exit", "Exit from shell()", builtin_exit}, + {"export", "Set environment variable", builtin_export}, + {"fg", "Bring job into the foreground", builtin_fg_bg}, + {"jobs", "Lists the active jobs", builtin_jobs}, + {"pwd", "Print current directory", builtin_pwd}, + {"read", "Input environment variable", builtin_read}, + {"return", "Return from a function", builtin_not_written}, + {"set", "Set/unset shell local variables", builtin_set}, + {"shift", "Shift positional parameters", builtin_shift}, + {"trap", "Trap signals", builtin_not_written}, + {"ulimit","Controls resource limits", builtin_not_written}, + {"umask","Sets file creation mask", builtin_umask}, + {"unset", "Unset environment variable", builtin_unset}, + {".", "Source-in and run commands in a file", builtin_source}, + {"help", "List shell built-in commands", builtin_help}, + {NULL, NULL, NULL} +}; + +static const char *set_cwd(void) +{ + if(cwd==unknown) + cwd = NULL; /* xgetcwd(arg) called free(arg) */ + cwd = xgetcwd((char *)cwd); + if (!cwd) + cwd = unknown; + return cwd; +} + +/* built-in 'eval' handler */ +static int builtin_eval(struct child_prog *child) +{ + char *str = NULL; + int rcode = EXIT_SUCCESS; + + if (child->argv[1]) { + str = make_string(child->argv + 1); + parse_string_outer(str, FLAG_EXIT_FROM_LOOP | + FLAG_PARSE_SEMICOLON); + free(str); + rcode = last_return_code; + } + return rcode; +} + +/* built-in 'cd <path>' handler */ +static int builtin_cd(struct child_prog *child) +{ + char *newdir; + if (child->argv[1] == NULL) + newdir = getenv("HOME"); + else + newdir = child->argv[1]; + if (chdir(newdir)) { + printf("cd: %s: %s\n", newdir, strerror(errno)); + return EXIT_FAILURE; + } + set_cwd(); + return EXIT_SUCCESS; +} + +/* built-in 'env' handler */ +static int builtin_env(struct child_prog *dummy) +{ + char **e = environ; + if (e == NULL) return EXIT_FAILURE; + for (; *e; e++) { + puts(*e); + } + return EXIT_SUCCESS; +} + +/* built-in 'exec' handler */ +static int builtin_exec(struct child_prog *child) +{ + if (child->argv[1] == NULL) + return EXIT_SUCCESS; /* Really? */ + child->argv++; + pseudo_exec(child); + /* never returns */ +} + +/* built-in 'exit' handler */ +static int builtin_exit(struct child_prog *child) +{ + if (child->argv[1] == NULL) + exit(last_return_code); + exit (atoi(child->argv[1])); +} + +/* built-in 'export VAR=value' handler */ +static int builtin_export(struct child_prog *child) +{ + int res = 0; + char *name = child->argv[1]; + + if (name == NULL) { + return (builtin_env(child)); + } + + name = strdup(name); + + if(name) { + char *value = strchr(name, '='); + + if (!value) { + char *tmp; + /* They are exporting something without an =VALUE */ + + value = get_local_var(name); + if (value) { + size_t ln = strlen(name); + + tmp = realloc(name, ln+strlen(value)+2); + if(tmp==NULL) + res = -1; + else { + sprintf(tmp+ln, "=%s", value); + name = tmp; + } + } else { + /* bash does not return an error when trying to export + * an undefined variable. Do likewise. */ + res = 1; + } + } + } + if (res<0) + perror_msg("export"); + else if(res==0) + res = set_local_var(name, 1); + else + res = 0; + free(name); + return res; +} + +/* built-in 'fg' and 'bg' handler */ +static int builtin_fg_bg(struct child_prog *child) +{ + int i, jobnum; + struct pipe *pi=NULL; + + if (!interactive) + return EXIT_FAILURE; + /* If they gave us no args, assume they want the last backgrounded task */ + if (!child->argv[1]) { + for (pi = job_list; pi; pi = pi->next) { + if (pi->jobid == last_jobid) { + break; + } + } + if (!pi) { + error_msg("%s: no current job", child->argv[0]); + return EXIT_FAILURE; + } + } else { + if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { + error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); + return EXIT_FAILURE; + } + for (pi = job_list; pi; pi = pi->next) { + if (pi->jobid == jobnum) { + break; + } + } + if (!pi) { + error_msg("%s: %d: no such job", child->argv[0], jobnum); + return EXIT_FAILURE; + } + } + + if (*child->argv[0] == 'f') { + /* Put the job into the foreground. */ + tcsetpgrp(shell_terminal, pi->pgrp); + } + + /* Restart the processes in the job */ + for (i = 0; i < pi->num_progs; i++) + pi->progs[i].is_stopped = 0; + + if ( (i=kill(- pi->pgrp, SIGCONT)) < 0) { + if (i == ESRCH) { + remove_bg_job(pi); + } else { + perror_msg("kill (SIGCONT)"); + } + } + + pi->stopped_progs = 0; + return EXIT_SUCCESS; +} + +/* built-in 'help' handler */ +static int builtin_help(struct child_prog *dummy) +{ + struct built_in_command *x; + + printf("\nBuilt-in commands:\n"); + printf("-------------------\n"); + for (x = bltins; x->cmd; x++) { + if (x->descr==NULL) + continue; + printf("%s\t%s\n", x->cmd, x->descr); + } + printf("\n\n"); + return EXIT_SUCCESS; +} + +/* built-in 'jobs' handler */ +static int builtin_jobs(struct child_prog *child) +{ + struct pipe *job; + char *status_string; + + for (job = job_list; job; job = job->next) { + if (job->running_progs == job->stopped_progs) + status_string = "Stopped"; + else + status_string = "Running"; + + printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text); + } + return EXIT_SUCCESS; +} + + +/* built-in 'pwd' handler */ +static int builtin_pwd(struct child_prog *dummy) +{ + puts(set_cwd()); + return EXIT_SUCCESS; +} + +/* built-in 'read VAR' handler */ +static int builtin_read(struct child_prog *child) +{ + int res; + + if (child->argv[1]) { + char string[BUFSIZ]; + char *var = 0; + + string[0] = 0; /* In case stdin has only EOF */ + /* read string */ + fgets(string, sizeof(string), stdin); + chomp(string); + var = malloc(strlen(child->argv[1])+strlen(string)+2); + if(var) { + sprintf(var, "%s=%s", child->argv[1], string); + res = set_local_var(var, 0); + } else + res = -1; + if (res) + fprintf(stderr, "read: %m\n"); + free(var); /* So not move up to avoid breaking errno */ + return res; + } else { + do res=getchar(); while(res!='\n' && res!=EOF); + return 0; + } +} + +/* built-in 'set VAR=value' handler */ +static int builtin_set(struct child_prog *child) +{ + char *temp = child->argv[1]; + struct variables *e; + + if (temp == NULL) + for(e = top_vars; e; e=e->next) + printf("%s=%s\n", e->name, e->value); + else + set_local_var(temp, 0); + + return EXIT_SUCCESS; +} + + +/* Built-in 'shift' handler */ +static int builtin_shift(struct child_prog *child) +{ + int n=1; + if (child->argv[1]) { + n=atoi(child->argv[1]); + } + if (n>=0 && n<global_argc) { + /* XXX This probably breaks $0 */ + global_argc -= n; + global_argv += n; + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } +} + +/* Built-in '.' handler (read-in and execute commands from file) */ +static int builtin_source(struct child_prog *child) +{ + FILE *input; + int status; + + if (child->argv[1] == NULL) + return EXIT_FAILURE; + + /* XXX search through $PATH is missing */ + input = fopen(child->argv[1], "r"); + if (!input) { + error_msg("Couldn't open file '%s'", child->argv[1]); + return EXIT_FAILURE; + } + + /* Now run the file */ + /* XXX argv and argc are broken; need to save old global_argv + * (pointer only is OK!) on this stack frame, + * set global_argv=child->argv+1, recurse, and restore. */ + mark_open(fileno(input)); + status = parse_file_outer(input); + mark_closed(fileno(input)); + fclose(input); + return (status); +} + +static int builtin_umask(struct child_prog *child) +{ + mode_t new_umask; + const char *arg = child->argv[1]; + char *end; + if (arg) { + new_umask=strtoul(arg, &end, 8); + if (*end!='\0' || end == arg) { + return EXIT_FAILURE; + } + } else { + printf("%.3o\n", (unsigned int) (new_umask=umask(0))); + } + umask(new_umask); + return EXIT_SUCCESS; +} + +/* built-in 'unset VAR' handler */ +static int builtin_unset(struct child_prog *child) +{ + /* bash returned already true */ + unset_local_var(child->argv[1]); + return EXIT_SUCCESS; +} + +static int builtin_not_written(struct child_prog *child) +{ + printf("builtin_%s not written\n",child->argv[0]); + return EXIT_FAILURE; +} +#endif + +static int b_check_space(o_string *o, int len) +{ + /* It would be easy to drop a more restrictive policy + * in here, such as setting a maximum string length */ + if (o->length + len > o->maxlen) { + char *old_data = o->data; + /* assert (data == NULL || o->maxlen != 0); */ + o->maxlen += max(2*len, B_CHUNK); + o->data = realloc(o->data, 1 + o->maxlen); + if (o->data == NULL) { + free(old_data); + } + } + return o->data == NULL; +} + +static int b_addchr(o_string *o, int ch) +{ + debug_printf("b_addchr: %c %d %p\n", ch, o->length, o); + if (b_check_space(o, 1)) return B_NOSPAC; + o->data[o->length] = ch; + o->length++; + o->data[o->length] = '\0'; + return 0; +} + +static void b_reset(o_string *o) +{ + o->length = 0; + o->nonnull = 0; + if (o->data != NULL) *o->data = '\0'; +} + +static void b_free(o_string *o) +{ + b_reset(o); + if (o->data != NULL) free(o->data); + o->data = NULL; + o->maxlen = 0; +} + +/* My analysis of quoting semantics tells me that state information + * is associated with a destination, not a source. + */ +static int b_addqchr(o_string *o, int ch, int quote) +{ + if (quote && strchr("*?[\\",ch)) { + int rc; + rc = b_addchr(o, '\\'); + if (rc) return rc; + } + return b_addchr(o, ch); +} + +/* belongs in utility.c */ +char *simple_itoa(unsigned int i) +{ + /* 21 digits plus null terminator, good for 64-bit or smaller ints */ + static char local[22]; + char *p = &local[21]; + *p-- = '\0'; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; +} + +static int b_adduint(o_string *o, unsigned int i) +{ + int r; + char *p = simple_itoa(i); + /* no escape checking necessary */ + do r=b_addchr(o, *p++); while (r==0 && *p); + return r; +} + +static int static_get(struct in_str *i) +{ + int ch=*i->p++; + if (ch=='\0') return EOF; + return ch; +} + +static int static_peek(struct in_str *i) +{ + return *i->p; +} + +#ifndef __U_BOOT__ +static inline void cmdedit_set_initial_prompt(void) +{ +#ifndef BB_FEATURE_SH_FANCY_PROMPT + PS1 = NULL; +#else + PS1 = getenv("PS1"); + if(PS1==0) + PS1 = "\\w \\$ "; +#endif +} + +static inline void setup_prompt_string(int promptmode, char **prompt_str) +{ + debug_printf("setup_prompt_string %d ",promptmode); +#ifndef BB_FEATURE_SH_FANCY_PROMPT + /* Set up the prompt */ + if (promptmode == 1) { + if (PS1) + free(PS1); + PS1=xmalloc(strlen(cwd)+4); + sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# "); + *prompt_str = PS1; + } else { + *prompt_str = PS2; + } +#else + *prompt_str = (promptmode==1)? PS1 : PS2; +#endif + debug_printf("result %s\n",*prompt_str); +} +#endif + +static void get_user_input(struct in_str *i) +{ +#ifndef __U_BOOT__ + char *prompt_str; + static char the_command[BUFSIZ]; + + setup_prompt_string(i->promptmode, &prompt_str); +#ifdef BB_FEATURE_COMMAND_EDITING + /* + ** enable command line editing only while a command line + ** is actually being read; otherwise, we'll end up bequeathing + ** atexit() handlers and other unwanted stuff to our + ** child processes (rob@sysgo.de) + */ + cmdedit_read_input(prompt_str, the_command); +#else + fputs(prompt_str, stdout); + fflush(stdout); + the_command[0]=fgetc(i->file); + the_command[1]='\0'; +#endif + fflush(stdout); + i->p = the_command; +#else + extern char console_buffer[CFG_CBSIZE]; + int n; + static char the_command[CFG_CBSIZE]; + + i->__promptme = 1; + if (i->promptmode == 1) { + n = readline(CFG_PROMPT); + } else { + n = readline(CFG_PROMPT_HUSH_PS2); + } + if (n == -1 ) { + flag_repeat = 0; + i->__promptme = 0; + } + n = strlen(console_buffer); + console_buffer[n] = '\n'; + console_buffer[n+1]= '\0'; + if (had_ctrlc()) flag_repeat = 0; + clear_ctrlc(); + do_repeat = 0; + if (i->promptmode == 1) { + if (console_buffer[0] == '\n'&& flag_repeat == 0) { + strcpy(the_command,console_buffer); + } + else { + if (console_buffer[0] != '\n') { + strcpy(the_command,console_buffer); + flag_repeat = 1; + } + else { + do_repeat = 1; + } + } + i->p = the_command; + } + else { + if (console_buffer[0] != '\n') { + if (strlen(the_command) + strlen(console_buffer) + < CFG_CBSIZE) { + n = strlen(the_command); + the_command[n-1] = ' '; + strcpy(&the_command[n],console_buffer); + } + else { + the_command[0] = '\n'; + the_command[1] = '\0'; + flag_repeat = 0; + } + } + if (i->__promptme == 0) { + the_command[0] = '\n'; + the_command[1] = '\0'; + } + i->p = console_buffer; + } +#endif +} + +/* This is the magic location that prints prompts + * and gets data back from the user */ +static int file_get(struct in_str *i) +{ + int ch; + + ch = 0; + /* If there is data waiting, eat it up */ + if (i->p && *i->p) { + ch=*i->p++; + } else { + /* need to double check i->file because we might be doing something + * more complicated by now, like sourcing or substituting. */ +#ifndef __U_BOOT__ + if (i->__promptme && interactive && i->file == stdin) { + while(! i->p || (interactive && strlen(i->p)==0) ) { +#else + while(! i->p || strlen(i->p)==0 ) { +#endif + get_user_input(i); + } + i->promptmode=2; +#ifndef __U_BOOT__ + i->__promptme = 0; +#endif + if (i->p && *i->p) { + ch=*i->p++; + } +#ifndef __U_BOOT__ + } else { + ch = fgetc(i->file); + } + +#endif + debug_printf("b_getch: got a %d\n", ch); + } +#ifndef __U_BOOT__ + if (ch == '\n') i->__promptme=1; +#endif + return ch; +} + +/* All the callers guarantee this routine will never be + * used right after a newline, so prompting is not needed. + */ +static int file_peek(struct in_str *i) +{ +#ifndef __U_BOOT__ + if (i->p && *i->p) { +#endif + return *i->p; +#ifndef __U_BOOT__ + } else { + i->peek_buf[0] = fgetc(i->file); + i->peek_buf[1] = '\0'; + i->p = i->peek_buf; + debug_printf("b_peek: got a %d\n", *i->p); + return *i->p; + } +#endif +} + +#ifndef __U_BOOT__ +static void setup_file_in_str(struct in_str *i, FILE *f) +#else +static void setup_file_in_str(struct in_str *i) +#endif +{ + i->peek = file_peek; + i->get = file_get; + i->__promptme=1; + i->promptmode=1; +#ifndef __U_BOOT__ + i->file = f; +#endif + i->p = NULL; +} + +static void setup_string_in_str(struct in_str *i, const char *s) +{ + i->peek = static_peek; + i->get = static_get; + i->__promptme=1; + i->promptmode=1; + i->p = s; +} + +#ifndef __U_BOOT__ +static void mark_open(int fd) +{ + struct close_me *new = xmalloc(sizeof(struct close_me)); + new->fd = fd; + new->next = close_me_head; + close_me_head = new; +} + +static void mark_closed(int fd) +{ + struct close_me *tmp; + if (close_me_head == NULL || close_me_head->fd != fd) + error_msg_and_die("corrupt close_me"); + tmp = close_me_head; + close_me_head = close_me_head->next; + free(tmp); +} + +static void close_all() +{ + struct close_me *c; + for (c=close_me_head; c; c=c->next) { + close(c->fd); + } + close_me_head = NULL; +} + +/* squirrel != NULL means we squirrel away copies of stdin, stdout, + * and stderr if they are redirected. */ +static int setup_redirects(struct child_prog *prog, int squirrel[]) +{ + int openfd, mode; + struct redir_struct *redir; + + for (redir=prog->redirects; redir; redir=redir->next) { + if (redir->dup == -1 && redir->word.gl_pathv == NULL) { + /* something went wrong in the parse. Pretend it didn't happen */ + continue; + } + if (redir->dup == -1) { + mode=redir_table[redir->type].mode; + openfd = open(redir->word.gl_pathv[0], mode, 0666); + if (openfd < 0) { + /* this could get lost if stderr has been redirected, but + bash and ash both lose it as well (though zsh doesn't!) */ + perror_msg("error opening %s", redir->word.gl_pathv[0]); + return 1; + } + } else { + openfd = redir->dup; + } + + if (openfd != redir->fd) { + if (squirrel && redir->fd < 3) { + squirrel[redir->fd] = dup(redir->fd); + } + if (openfd == -3) { + close(openfd); + } else { + dup2(openfd, redir->fd); + if (redir->dup == -1) + close (openfd); + } + } + } + return 0; +} + +static void restore_redirects(int squirrel[]) +{ + int i, fd; + for (i=0; i<3; i++) { + fd = squirrel[i]; + if (fd != -1) { + /* No error checking. I sure wouldn't know what + * to do with an error if I found one! */ + dup2(fd, i); + close(fd); + } + } +} + +/* never returns */ +/* XXX no exit() here. If you don't exec, use _exit instead. + * The at_exit handlers apparently confuse the calling process, + * in particular stdin handling. Not sure why? */ +static void pseudo_exec(struct child_prog *child) +{ + int i, rcode; + char *p; + struct built_in_command *x; + if (child->argv) { + for (i=0; is_assignment(child->argv[i]); i++) { + debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]); + p = insert_var_value(child->argv[i]); + putenv(strdup(p)); + if (p != child->argv[i]) free(p); + } + child->argv+=i; /* XXX this hack isn't so horrible, since we are about + to exit, and therefore don't need to keep data + structures consistent for free() use. */ + /* If a variable is assigned in a forest, and nobody listens, + * was it ever really set? + */ + if (child->argv[0] == NULL) { + _exit(EXIT_SUCCESS); + } + + /* + * Check if the command matches any of the builtins. + * Depending on context, this might be redundant. But it's + * easier to waste a few CPU cycles than it is to figure out + * if this is one of those cases. + */ + for (x = bltins; x->cmd; x++) { + if (strcmp(child->argv[0], x->cmd) == 0 ) { + debug_printf("builtin exec %s\n", child->argv[0]); + rcode = x->function(child); + fflush(stdout); + _exit(rcode); + } + } + + /* Check if the command matches any busybox internal commands + * ("applets") here. + * FIXME: This feature is not 100% safe, since + * BusyBox is not fully reentrant, so we have no guarantee the things + * from the .bss are still zeroed, or that things from .data are still + * at their defaults. We could exec ourself from /proc/self/exe, but I + * really dislike relying on /proc for things. We could exec ourself + * from global_argv[0], but if we are in a chroot, we may not be able + * to find ourself... */ +#ifdef BB_FEATURE_SH_STANDALONE_SHELL + { + int argc_l; + char** argv_l=child->argv; + char *name = child->argv[0]; + +#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN + /* Following discussions from November 2000 on the busybox mailing + * list, the default configuration, (without + * get_last_path_component()) lets the user force use of an + * external command by specifying the full (with slashes) filename. + * If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then applets + * _aways_ override external commands, so if you want to run + * /bin/cat, it will use BusyBox cat even if /bin/cat exists on the + * filesystem and is _not_ busybox. Some systems may want this, + * most do not. */ + name = get_last_path_component(name); +#endif + /* Count argc for use in a second... */ + for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); + optind = 1; + debug_printf("running applet %s\n", name); + run_applet_by_name(name, argc_l, child->argv); + } +#endif + debug_printf("exec of %s\n",child->argv[0]); + execvp(child->argv[0],child->argv); + perror_msg("couldn't exec: %s",child->argv[0]); + _exit(1); + } else if (child->group) { + debug_printf("runtime nesting to group\n"); + interactive=0; /* crucial!!!! */ + rcode = run_list_real(child->group); + /* OK to leak memory by not calling free_pipe_list, + * since this process is about to exit */ + _exit(rcode); + } else { + /* Can happen. See what bash does with ">foo" by itself. */ + debug_printf("trying to pseudo_exec null command\n"); + _exit(EXIT_SUCCESS); + } +} + +static void insert_bg_job(struct pipe *pi) +{ + struct pipe *thejob; + + /* Linear search for the ID of the job to use */ + pi->jobid = 1; + for (thejob = job_list; thejob; thejob = thejob->next) + if (thejob->jobid >= pi->jobid) + pi->jobid = thejob->jobid + 1; + + /* add thejob to the list of running jobs */ + if (!job_list) { + thejob = job_list = xmalloc(sizeof(*thejob)); + } else { + for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */; + thejob->next = xmalloc(sizeof(*thejob)); + thejob = thejob->next; + } + + /* physically copy the struct job */ + memcpy(thejob, pi, sizeof(struct pipe)); + thejob->next = NULL; + thejob->running_progs = thejob->num_progs; + thejob->stopped_progs = 0; + thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */ + + /*if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0]) */ + { + char *bar=thejob->text; + char **foo=pi->progs[0].argv; + while(foo && *foo) { + bar += sprintf(bar, "%s ", *foo++); + } + } + + /* we don't wait for background thejobs to return -- append it + to the list of backgrounded thejobs and leave it alone */ + printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid); + last_bg_pid = thejob->progs[0].pid; + last_jobid = thejob->jobid; +} + +/* remove a backgrounded job */ +static void remove_bg_job(struct pipe *pi) +{ + struct pipe *prev_pipe; + + if (pi == job_list) { + job_list = pi->next; + } else { + prev_pipe = job_list; + while (prev_pipe->next != pi) + prev_pipe = prev_pipe->next; + prev_pipe->next = pi->next; + } + if (job_list) + last_jobid = job_list->jobid; + else + last_jobid = 0; + + pi->stopped_progs = 0; + free_pipe(pi, 0); + free(pi); +} + +/* Checks to see if any processes have exited -- if they + have, figure out why and see if a job has completed */ +static int checkjobs(struct pipe* fg_pipe) +{ + int attributes; + int status; + int prognum = 0; + struct pipe *pi; + pid_t childpid; + + attributes = WUNTRACED; + if (fg_pipe==NULL) { + attributes |= WNOHANG; + } + + while ((childpid = waitpid(-1, &status, attributes)) > 0) { + if (fg_pipe) { + int i, rcode = 0; + for (i=0; i < fg_pipe->num_progs; i++) { + if (fg_pipe->progs[i].pid == childpid) { + if (i==fg_pipe->num_progs-1) + rcode=WEXITSTATUS(status); + (fg_pipe->num_progs)--; + return(rcode); + } + } + } + + for (pi = job_list; pi; pi = pi->next) { + prognum = 0; + while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) { + prognum++; + } + if (prognum < pi->num_progs) + break; + } + + if(pi==NULL) { + debug_printf("checkjobs: pid %d was not in our list!\n", childpid); + continue; + } + + if (WIFEXITED(status) || WIFSIGNALED(status)) { + /* child exited */ + pi->running_progs--; + pi->progs[prognum].pid = 0; + + if (!pi->running_progs) { + printf(JOB_STATUS_FORMAT, pi->jobid, "Done", pi->text); + remove_bg_job(pi); + } + } else { + /* child stopped */ + pi->stopped_progs++; + pi->progs[prognum].is_stopped = 1; + +#if 0 + /* Printing this stuff is a pain, since it tends to + * overwrite the prompt an inconveinient moments. So + * don't do that. */ + if (pi->stopped_progs == pi->num_progs) { + printf("\n"JOB_STATUS_FORMAT, pi->jobid, "Stopped", pi->text); + } +#endif + } + } + + if (childpid == -1 && errno != ECHILD) + perror_msg("waitpid"); + + /* move the shell to the foreground */ + /*if (interactive && tcsetpgrp(shell_terminal, getpgid(0))) */ + /* perror_msg("tcsetpgrp-2"); */ + return -1; +} + +/* Figure out our controlling tty, checking in order stderr, + * stdin, and stdout. If check_pgrp is set, also check that + * we belong to the foreground process group associated with + * that tty. The value of shell_terminal is needed in order to call + * tcsetpgrp(shell_terminal, ...); */ +void controlling_tty(int check_pgrp) +{ + pid_t curpgrp; + + if ((curpgrp = tcgetpgrp(shell_terminal = 2)) < 0 + && (curpgrp = tcgetpgrp(shell_terminal = 0)) < 0 + && (curpgrp = tcgetpgrp(shell_terminal = 1)) < 0) + goto shell_terminal_error; + + if (check_pgrp && curpgrp != getpgid(0)) + goto shell_terminal_error; + + return; + +shell_terminal_error: + shell_terminal = -1; + return; +} +#endif + +/* run_pipe_real() starts all the jobs, but doesn't wait for anything + * to finish. See checkjobs(). + * + * return code is normally -1, when the caller has to wait for children + * to finish to determine the exit status of the pipe. If the pipe + * is a simple builtin command, however, the action is done by the + * time run_pipe_real returns, and the exit code is provided as the + * return value. + * + * The input of the pipe is always stdin, the output is always + * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus, + * because it tries to avoid running the command substitution in + * subshell, when that is in fact necessary. The subshell process + * now has its stdout directed to the input of the appropriate pipe, + * so this routine is noticeably simpler. + */ +static int run_pipe_real(struct pipe *pi) +{ + int i; +#ifndef __U_BOOT__ + int nextin, nextout; + int pipefds[2]; /* pipefds[0] is for reading */ + struct child_prog *child; + struct built_in_command *x; + char *p; +#else + int nextin; + int flag = do_repeat ? CMD_FLAG_REPEAT : 0; + struct child_prog *child; + cmd_tbl_t *cmdtp; + char *p; +#endif + + nextin = 0; +#ifndef __U_BOOT__ + pi->pgrp = -1; +#endif + + /* Check if this is a simple builtin (not part of a pipe). + * Builtins within pipes have to fork anyway, and are handled in + * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. + */ + if (pi->num_progs == 1) child = & (pi->progs[0]); +#ifndef __U_BOOT__ + if (pi->num_progs == 1 && child->group && child->subshell == 0) { + int squirrel[] = {-1, -1, -1}; + int rcode; + debug_printf("non-subshell grouping\n"); + setup_redirects(child, squirrel); + /* XXX could we merge code with following builtin case, + * by creating a pseudo builtin that calls run_list_real? */ + rcode = run_list_real(child->group); + restore_redirects(squirrel); +#else + if (pi->num_progs == 1 && child->group) { + int rcode; + debug_printf("non-subshell grouping\n"); + rcode = run_list_real(child->group); +#endif + return rcode; + } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { + for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ } + if (i!=0 && child->argv[i]==NULL) { + /* assignments, but no command: set the local environment */ + for (i=0; child->argv[i]!=NULL; i++) { + + /* Ok, this case is tricky. We have to decide if this is a + * local variable, or an already exported variable. If it is + * already exported, we have to export the new value. If it is + * not exported, we need only set this as a local variable. + * This junk is all to decide whether or not to export this + * variable. */ + int export_me=0; + char *name, *value; + name = xstrdup(child->argv[i]); + debug_printf("Local environment set: %s\n", name); + value = strchr(name, '='); + if (value) + *value=0; +#ifndef __U_BOOT__ + if ( get_local_var(name)) { + export_me=1; + } +#endif + free(name); + p = insert_var_value(child->argv[i]); + set_local_var(p, export_me); + if (p != child->argv[i]) free(p); + } + return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ + } + for (i = 0; is_assignment(child->argv[i]); i++) { + p = insert_var_value(child->argv[i]); +#ifndef __U_BOOT__ + putenv(strdup(p)); +#else + set_local_var(p, 0); +#endif + if (p != child->argv[i]) { + child->sp--; + free(p); + } + } + if (child->sp) { + char * str = NULL; + + str = make_string((child->argv + i)); + parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); + free(str); + return last_return_code; + } +#ifndef __U_BOOT__ + for (x = bltins; x->cmd; x++) { + if (strcmp(child->argv[i], x->cmd) == 0 ) { + int squirrel[] = {-1, -1, -1}; + int rcode; + if (x->function == builtin_exec && child->argv[i+1]==NULL) { + debug_printf("magic exec\n"); + setup_redirects(child,NULL); + return EXIT_SUCCESS; + } + debug_printf("builtin inline %s\n", child->argv[0]); + /* XXX setup_redirects acts on file descriptors, not FILEs. + * This is perfect for work that comes after exec(). + * Is it really safe for inline use? Experimentally, + * things seem to work with glibc. */ + setup_redirects(child, squirrel); +#else + /* check ";", because ,example , argv consist from + * "help;flinfo" must not execute + */ + if (strchr(child->argv[i], ';')) { + printf ("Unknown command '%s' - try 'help' or use 'run' command\n", + child->argv[i]); + return -1; + } + /* Look up command in command table */ + if ((cmdtp = find_cmd(child->argv[i])) == NULL) { + printf ("Unknown command '%s' - try 'help'\n", child->argv[i]); + return -1; /* give up after bad command */ + } else { + int rcode; +#if (CONFIG_COMMANDS & CFG_CMD_BOOTD) + /* avoid "bootd" recursion */ + if (cmdtp->cmd == do_bootd) { + if (flag & CMD_FLAG_BOOTD) { + printf ("'bootd' recursion detected\n"); + return -1; + } + else + flag |= CMD_FLAG_BOOTD; + } +#endif /* CFG_CMD_BOOTD */ + /* found - check max args */ + if ((child->argc - i) > cmdtp->maxargs) { + printf ("Usage:\n%s\n", cmdtp->usage); + return -1; + } +#endif + child->argv+=i; /* XXX horrible hack */ +#ifndef __U_BOOT__ + rcode = x->function(child); +#else + /* OK - call function to do the command */ + rcode = (cmdtp->cmd) + (cmdtp, flag,child->argc-i,&child->argv[i]); + if ( !cmdtp->repeatable ) + flag_repeat = 0; +#endif + child->argv-=i; /* XXX restore hack so free() can work right */ +#ifndef __U_BOOT__ + restore_redirects(squirrel); +#endif + return rcode; + } + } +#ifndef __U_BOOT__ + } + + for (i = 0; i < pi->num_progs; i++) { + child = & (pi->progs[i]); + + /* pipes are inserted between pairs of commands */ + if ((i + 1) < pi->num_progs) { + if (pipe(pipefds)<0) perror_msg_and_die("pipe"); + nextout = pipefds[1]; + } else { + nextout=1; + pipefds[0] = -1; + } + + /* XXX test for failed fork()? */ + if (!(child->pid = fork())) { + /* Set the handling for job control signals back to the default. */ + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + close_all(); + + if (nextin != 0) { + dup2(nextin, 0); + close(nextin); + } + if (nextout != 1) { + dup2(nextout, 1); + close(nextout); + } + if (pipefds[0]!=-1) { + close(pipefds[0]); /* opposite end of our output pipe */ + } + + /* Like bash, explicit redirects override pipes, + * and the pipe fd is available for dup'ing. */ + setup_redirects(child,NULL); + + if (interactive && pi->followup!=PIPE_BG) { + /* If we (the child) win the race, put ourselves in the process + * group whose leader is the first process in this pipe. */ + if (pi->pgrp < 0) { + pi->pgrp = getpid(); + } + if (setpgid(0, pi->pgrp) == 0) { + tcsetpgrp(2, pi->pgrp); + } + } + + pseudo_exec(child); + } + + + /* put our child in the process group whose leader is the + first process in this pipe */ + if (pi->pgrp < 0) { + pi->pgrp = child->pid; + } + /* Don't check for errors. The child may be dead already, + * in which case setpgid returns error code EACCES. */ + setpgid(child->pid, pi->pgrp); + + if (nextin != 0) + close(nextin); + if (nextout != 1) + close(nextout); + + /* If there isn't another process, nextin is garbage + but it doesn't matter */ + nextin = pipefds[0]; + } +#endif + return -1; +} + +static int run_list_real(struct pipe *pi) +{ + char *save_name = NULL; + char **list = NULL; + char **save_list = NULL; + struct pipe *rpipe; + int flag_rep = 0; +#ifndef __U_BOOT__ + int save_num_progs; +#endif + int rcode=0, flag_skip=1; + int flag_restore = 0; + int if_code=0, next_if_code=0; /* need double-buffer to handle elif */ + reserved_style rmode, skip_more_in_this_rmode=RES_XXXX; + /* check syntax for "for" */ + for (rpipe = pi; rpipe; rpipe = rpipe->next) { + if ((rpipe->r_mode == RES_IN || + rpipe->r_mode == RES_FOR) && + (rpipe->next == NULL)) { + syntax(); +#ifdef __U_BOOT__ + flag_repeat = 0; +#endif + return 1; + } + if ((rpipe->r_mode == RES_IN && + (rpipe->next->r_mode == RES_IN && + rpipe->next->progs->argv != NULL))|| + (rpipe->r_mode == RES_FOR && + rpipe->next->r_mode != RES_IN)) { + syntax(); +#ifdef __U_BOOT__ + flag_repeat = 0; +#endif + return 1; + } + } + for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) { + if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL || + pi->r_mode == RES_FOR) { +#ifdef __U_BOOT__ + /* check Ctrl-C */ + ctrlc(); + if ((had_ctrlc())) { + return 1; + } +#endif + flag_restore = 0; + if (!rpipe) { + flag_rep = 0; + rpipe = pi; + } + } + rmode = pi->r_mode; + debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", rmode, if_code, next_if_code, skip_more_in_this_rmode); + if (rmode == skip_more_in_this_rmode && flag_skip) { + if (pi->followup == PIPE_SEQ) flag_skip=0; + continue; + } + flag_skip = 1; + skip_more_in_this_rmode = RES_XXXX; + if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code; + if (rmode == RES_THEN && if_code) continue; + if (rmode == RES_ELSE && !if_code) continue; + if (rmode == RES_ELIF && !if_code) continue; + if (rmode == RES_FOR && pi->num_progs) { + if (!list) { + /* if no variable values after "in" we skip "for" */ + if (!pi->next->progs->argv) continue; + /* create list of variable values */ + list = make_list_in(pi->next->progs->argv, + pi->progs->argv[0]); + save_list = list; + save_name = pi->progs->argv[0]; + pi->progs->argv[0] = NULL; + flag_rep = 1; + } + if (!(*list)) { + free(pi->progs->argv[0]); + free(save_list); + list = NULL; + flag_rep = 0; + pi->progs->argv[0] = save_name; +#ifndef __U_BOOT__ + pi->progs->glob_result.gl_pathv[0] = + pi->progs->argv[0]; +#endif + continue; + } else { + /* insert new value from list for variable */ + if (pi->progs->argv[0]) + free(pi->progs->argv[0]); + pi->progs->argv[0] = *list++; +#ifndef __U_BOOT__ + pi->progs->glob_result.gl_pathv[0] = + pi->progs->argv[0]; +#endif + } + } + if (rmode == RES_IN) continue; + if (rmode == RES_DO) { + if (!flag_rep) continue; + } + if ((rmode == RES_DONE)) { + if (flag_rep) { + flag_restore = 1; + } else { + rpipe = NULL; + } + } + if (pi->num_progs == 0) continue; +#ifndef __U_BOOT__ + save_num_progs = pi->num_progs; /* save number of programs */ +#endif + rcode = run_pipe_real(pi); + debug_printf("run_pipe_real returned %d\n",rcode); +#ifndef __U_BOOT__ + if (rcode!=-1) { + /* We only ran a builtin: rcode was set by the return value + * of run_pipe_real(), and we don't need to wait for anything. */ + } else if (pi->followup==PIPE_BG) { + /* XXX check bash's behavior with nontrivial pipes */ + /* XXX compute jobid */ + /* XXX what does bash do with attempts to background builtins? */ + insert_bg_job(pi); + rcode = EXIT_SUCCESS; + } else { + if (interactive) { + /* move the new process group into the foreground */ + if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY) + perror_msg("tcsetpgrp-3"); + rcode = checkjobs(pi); + /* move the shell to the foreground */ + if (tcsetpgrp(shell_terminal, getpgid(0)) && errno != ENOTTY) + perror_msg("tcsetpgrp-4"); + } else { + rcode = checkjobs(pi); + } + debug_printf("checkjobs returned %d\n",rcode); + } + last_return_code=rcode; +#else + last_return_code=(rcode == 0) ? 0 : 1; +#endif +#ifndef __U_BOOT__ + pi->num_progs = save_num_progs; /* restore number of programs */ +#endif + if ( rmode == RES_IF || rmode == RES_ELIF ) + next_if_code=rcode; /* can be overwritten a number of times */ + if (rmode == RES_WHILE) + flag_rep = !last_return_code; + if (rmode == RES_UNTIL) + flag_rep = last_return_code; + if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) || + (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) + skip_more_in_this_rmode=rmode; +#ifndef __U_BOOT__ + checkjobs(NULL); +#endif + } + return rcode; +} + +/* broken, of course, but OK for testing */ +static char *indenter(int i) +{ + static char blanks[]=" "; + return &blanks[sizeof(blanks)-i-1]; +} + +/* return code is the exit status of the pipe */ +static int free_pipe(struct pipe *pi, int indent) +{ + char **p; + struct child_prog *child; +#ifndef __U_BOOT__ + struct redir_struct *r, *rnext; +#endif + int a, i, ret_code=0; + char *ind = indenter(indent); + +#ifndef __U_BOOT__ + if (pi->stopped_progs > 0) + return ret_code; + final_printf("%s run pipe: (pid %d)\n",ind,getpid()); +#endif + for (i=0; i<pi->num_progs; i++) { + child = &pi->progs[i]; + final_printf("%s command %d:\n",ind,i); + if (child->argv) { + for (a=0,p=child->argv; *p; a++,p++) { + final_printf("%s argv[%d] = %s\n",ind,a,*p); + } +#ifndef __U_BOOT__ + globfree(&child->glob_result); +#else + for (a = child->argc;a >= 0;a--) { + free(child->argv[a]); + } + free(child->argv); + child->argc = 0; +#endif + child->argv=NULL; + } else if (child->group) { +#ifndef __U_BOOT__ + final_printf("%s begin group (subshell:%d)\n",ind, child->subshell); +#endif + ret_code = free_pipe_list(child->group,indent+3); + final_printf("%s end group\n",ind); + } else { + final_printf("%s (nil)\n",ind); + } +#ifndef __U_BOOT__ + for (r=child->redirects; r; r=rnext) { + final_printf("%s redirect %d%s", ind, r->fd, redir_table[r->type].descrip); + if (r->dup == -1) { + /* guard against the case >$FOO, where foo is unset or blank */ + if (r->word.gl_pathv) { + final_printf(" %s\n", *r->word.gl_pathv); + globfree(&r->word); + } + } else { + final_printf("&%d\n", r->dup); + } + rnext=r->next; + free(r); + } + child->redirects=NULL; +#endif + } + free(pi->progs); /* children are an array, they get freed all at once */ + pi->progs=NULL; + return ret_code; +} + +static int free_pipe_list(struct pipe *head, int indent) +{ + int rcode=0; /* if list has no members */ + struct pipe *pi, *next; + char *ind = indenter(indent); + for (pi=head; pi; pi=next) { + final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); + rcode = free_pipe(pi, indent); + final_printf("%s pipe followup code %d\n", ind, pi->followup); + next=pi->next; + pi->next=NULL; + free(pi); + } + return rcode; +} + +/* Select which version we will use */ +static int run_list(struct pipe *pi) +{ + int rcode=0; +#ifndef __U_BOOT__ + if (fake_mode==0) { +#endif + rcode = run_list_real(pi); +#ifndef __U_BOOT__ + } +#endif + /* free_pipe_list has the side effect of clearing memory + * In the long run that function can be merged with run_list_real, + * but doing that now would hobble the debugging effort. */ + free_pipe_list(pi,0); + return rcode; +} + +/* The API for glob is arguably broken. This routine pushes a non-matching + * string into the output structure, removing non-backslashed backslashes. + * If someone can prove me wrong, by performing this function within the + * original glob(3) api, feel free to rewrite this routine into oblivion. + * Return code (0 vs. GLOB_NOSPACE) matches glob(3). + * XXX broken if the last character is '\\', check that before calling. + */ +#ifndef __U_BOOT__ +static int globhack(const char *src, int flags, glob_t *pglob) +{ + int cnt=0, pathc; + const char *s; + char *dest; + for (cnt=1, s=src; s && *s; s++) { + if (*s == '\\') s++; + cnt++; + } + dest = malloc(cnt); + if (!dest) return GLOB_NOSPACE; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathv=NULL; + pglob->gl_pathc=0; + pglob->gl_offs=0; + pglob->gl_offs=0; + } + pathc = ++pglob->gl_pathc; + pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv)); + if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; + pglob->gl_pathv[pathc-1]=dest; + pglob->gl_pathv[pathc]=NULL; + for (s=src; s && *s; s++, dest++) { + if (*s == '\\') s++; + *dest = *s; + } + *dest='\0'; + return 0; +} + +/* XXX broken if the last character is '\\', check that before calling */ +static int glob_needed(const char *s) +{ + for (; *s; s++) { + if (*s == '\\') s++; + if (strchr("*[?",*s)) return 1; + } + return 0; +} + +#if 0 +static void globprint(glob_t *pglob) +{ + int i; + debug_printf("glob_t at %p:\n", pglob); + debug_printf(" gl_pathc=%d gl_pathv=%p gl_offs=%d gl_flags=%d\n", + pglob->gl_pathc, pglob->gl_pathv, pglob->gl_offs, pglob->gl_flags); + for (i=0; i<pglob->gl_pathc; i++) + debug_printf("pglob->gl_pathv[%d] = %p = %s\n", i, + pglob->gl_pathv[i], pglob->gl_pathv[i]); +} +#endif + +static int xglob(o_string *dest, int flags, glob_t *pglob) +{ + int gr; + + /* short-circuit for null word */ + /* we can code this better when the debug_printf's are gone */ + if (dest->length == 0) { + if (dest->nonnull) { + /* bash man page calls this an "explicit" null */ + gr = globhack(dest->data, flags, pglob); + debug_printf("globhack returned %d\n",gr); + } else { + return 0; + } + } else if (glob_needed(dest->data)) { + gr = glob(dest->data, flags, NULL, pglob); + debug_printf("glob returned %d\n",gr); + if (gr == GLOB_NOMATCH) { + /* quote removal, or more accurately, backslash removal */ + gr = globhack(dest->data, flags, pglob); + debug_printf("globhack returned %d\n",gr); + } + } else { + gr = globhack(dest->data, flags, pglob); + debug_printf("globhack returned %d\n",gr); + } + if (gr == GLOB_NOSPACE) + error_msg_and_die("out of memory during glob"); + if (gr != 0) { /* GLOB_ABORTED ? */ + error_msg("glob(3) error %d",gr); + } + /* globprint(glob_target); */ + return gr; +} +#endif + +/* This is used to get/check local shell variables */ +static char *get_local_var(const char *s) +{ + struct variables *cur; + + if (!s) + return NULL; + for (cur = top_vars; cur; cur=cur->next) + if(strcmp(cur->name, s)==0) + return cur->value; + return NULL; +} + +/* This is used to set local shell variables + flg_export==0 if only local (not exporting) variable + flg_export==1 if "new" exporting environ + flg_export>1 if current startup environ (not call putenv()) */ +static int set_local_var(const char *s, int flg_export) +{ + char *name, *value; + int result=0; + struct variables *cur; + + name=strdup(s); + +#ifdef __U_BOOT__ + if (getenv(name) != NULL) { + printf ("ERROR: " + "There is a global environmet variable with the same name.\n"); + return -1; + } +#endif + /* Assume when we enter this function that we are already in + * NAME=VALUE format. So the first order of business is to + * split 's' on the '=' into 'name' and 'value' */ + value = strchr(name, '='); + if (value==0 && ++value==0) { + free(name); + return -1; + } + *value++ = 0; + + for(cur = top_vars; cur; cur = cur->next) { + if(strcmp(cur->name, name)==0) + break; + } + + if(cur) { + if(strcmp(cur->value, value)==0) { + if(flg_export>0 && cur->flg_export==0) + cur->flg_export=flg_export; + else + result++; + } else { + if(cur->flg_read_only) { + error_msg("%s: readonly variable", name); + result = -1; + } else { + if(flg_export>0 || cur->flg_export>1) + cur->flg_export=1; + free(cur->value); + + cur->value = strdup(value); + } + } + } else { + cur = malloc(sizeof(struct variables)); + if(!cur) { + result = -1; + } else { + cur->name = strdup(name); + if(cur->name == 0) { + free(cur); + result = -1; + } else { + struct variables *bottom = top_vars; + cur->value = strdup(value); + cur->next = 0; + cur->flg_export = flg_export; + cur->flg_read_only = 0; + while(bottom->next) bottom=bottom->next; + bottom->next = cur; + } + } + } + +#ifndef __U_BOOT__ + if(result==0 && cur->flg_export==1) { + *(value-1) = '='; + result = putenv(name); + } else { +#endif + free(name); +#ifndef __U_BOOT__ + if(result>0) /* equivalent to previous set */ + result = 0; + } +#endif + return result; +} + +#ifndef __U_BOOT__ +static void unset_local_var(const char *name) +{ + struct variables *cur; + + if (name) { + for (cur = top_vars; cur; cur=cur->next) { + if(strcmp(cur->name, name)==0) + break; + } + if(cur!=0) { + struct variables *next = top_vars; + if(cur->flg_read_only) { + error_msg("%s: readonly variable", name); + return; + } else { + if(cur->flg_export) + unsetenv(cur->name); + free(cur->name); + free(cur->value); + while (next->next != cur) + next = next->next; + next->next = cur->next; + } + free(cur); + } + } +} +#endif + +static int is_assignment(const char *s) +{ + if (s==NULL || !isalpha(*s)) return 0; + ++s; + while(isalnum(*s) || *s=='_') ++s; + return *s=='='; +} + +#ifndef __U_BOOT__ +/* the src parameter allows us to peek forward to a possible &n syntax + * for file descriptor duplication, e.g., "2>&1". + * Return code is 0 normally, 1 if a syntax error is detected in src. + * Resource errors (in xmalloc) cause the process to exit */ +static int setup_redirect(struct p_context *ctx, int fd, redir_type style, + struct in_str *input) +{ + struct child_prog *child=ctx->child; + struct redir_struct *redir = child->redirects; + struct redir_struct *last_redir=NULL; + + /* Create a new redir_struct and drop it onto the end of the linked list */ + while(redir) { + last_redir=redir; + redir=redir->next; + } + redir = xmalloc(sizeof(struct redir_struct)); + redir->next=NULL; + redir->word.gl_pathv=NULL; + if (last_redir) { + last_redir->next=redir; + } else { + child->redirects=redir; + } + + redir->type=style; + redir->fd= (fd==-1) ? redir_table[style].default_fd : fd ; + + debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); + + /* Check for a '2>&1' type redirect */ + redir->dup = redirect_dup_num(input); + if (redir->dup == -2) return 1; /* syntax error */ + if (redir->dup != -1) { + /* Erik had a check here that the file descriptor in question + * is legit; I postpone that to "run time" + * A "-" representation of "close me" shows up as a -3 here */ + debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup); + } else { + /* We do _not_ try to open the file that src points to, + * since we need to return and let src be expanded first. + * Set ctx->pending_redirect, so we know what to do at the + * end of the next parsed word. + */ + ctx->pending_redirect = redir; + } + return 0; +} +#endif + +struct pipe *new_pipe(void) { + struct pipe *pi; + pi = xmalloc(sizeof(struct pipe)); + pi->num_progs = 0; + pi->progs = NULL; + pi->next = NULL; + pi->followup = 0; /* invalid */ + return pi; +} + +static void initialize_context(struct p_context *ctx) +{ + ctx->pipe=NULL; +#ifndef __U_BOOT__ + ctx->pending_redirect=NULL; +#endif + ctx->child=NULL; + ctx->list_head=new_pipe(); + ctx->pipe=ctx->list_head; + ctx->w=RES_NONE; + ctx->stack=NULL; +#ifdef __U_BOOT__ + ctx->old_flag=0; +#endif + done_command(ctx); /* creates the memory for working child */ +} + +/* normal return is 0 + * if a reserved word is found, and processed, return 1 + * should handle if, then, elif, else, fi, for, while, until, do, done. + * case, function, and select are obnoxious, save those for later. + */ +int reserved_word(o_string *dest, struct p_context *ctx) +{ + struct reserved_combo { + char *literal; + int code; + long flag; + }; + /* Mostly a list of accepted follow-up reserved words. + * FLAG_END means we are done with the sequence, and are ready + * to turn the compound list into a command. + * FLAG_START means the word must start a new compound list. + */ + static struct reserved_combo reserved_list[] = { + { "if", RES_IF, FLAG_THEN | FLAG_START }, + { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI }, + { "elif", RES_ELIF, FLAG_THEN }, + { "else", RES_ELSE, FLAG_FI }, + { "fi", RES_FI, FLAG_END }, + { "for", RES_FOR, FLAG_IN | FLAG_START }, + { "while", RES_WHILE, FLAG_DO | FLAG_START }, + { "until", RES_UNTIL, FLAG_DO | FLAG_START }, + { "in", RES_IN, FLAG_DO }, + { "do", RES_DO, FLAG_DONE }, + { "done", RES_DONE, FLAG_END } + }; + struct reserved_combo *r; + for (r=reserved_list; +#define NRES sizeof(reserved_list)/sizeof(struct reserved_combo) + r<reserved_list+NRES; r++) { + if (strcmp(dest->data, r->literal) == 0) { + debug_printf("found reserved word %s, code %d\n",r->literal,r->code); + if (r->flag & FLAG_START) { + struct p_context *new = xmalloc(sizeof(struct p_context)); + debug_printf("push stack\n"); + if (ctx->w == RES_IN || ctx->w == RES_FOR) { + syntax(); + free(new); + ctx->w = RES_SNTX; + b_reset(dest); + return 1; + } + *new = *ctx; /* physical copy */ + initialize_context(ctx); + ctx->stack=new; + } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) { + syntax(); + ctx->w = RES_SNTX; + b_reset(dest); + return 1; + } + ctx->w=r->code; + ctx->old_flag = r->flag; + if (ctx->old_flag & FLAG_END) { + struct p_context *old; + debug_printf("pop stack\n"); + done_pipe(ctx,PIPE_SEQ); + old = ctx->stack; + old->child->group = ctx->list_head; +#ifndef __U_BOOT__ + old->child->subshell = 0; +#endif + *ctx = *old; /* physical copy */ + free(old); + } + b_reset (dest); + return 1; + } + } + return 0; +} + +/* normal return is 0. + * Syntax or xglob errors return 1. */ +static int done_word(o_string *dest, struct p_context *ctx) +{ + struct child_prog *child=ctx->child; +#ifndef __U_BOOT__ + glob_t *glob_target; + int gr, flags = 0; +#else + char *str, *s; + int argc, cnt; +#endif + + debug_printf("done_word: %s %p\n", dest->data, child); + if (dest->length == 0 && !dest->nonnull) { + debug_printf(" true null, ignored\n"); + return 0; + } +#ifndef __U_BOOT__ + if (ctx->pending_redirect) { + glob_target = &ctx->pending_redirect->word; + } else { +#endif + if (child->group) { + syntax(); + return 1; /* syntax error, groups and arglists don't mix */ + } + if (!child->argv && (ctx->type & FLAG_PARSE_SEMICOLON)) { + debug_printf("checking %s for reserved-ness\n",dest->data); + if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX; + } +#ifndef __U_BOOT__ + glob_target = &child->glob_result; + if (child->argv) flags |= GLOB_APPEND; +#else + for (cnt = 1, s = dest->data; s && *s; s++) { + if (*s == '\\') s++; + cnt++; + } + str = malloc(cnt); + if (!str) return 1; + if ( child->argv == NULL) { + child->argc=0; + } + argc = ++child->argc; + child->argv = realloc(child->argv, (argc+1)*sizeof(*child->argv)); + if (child->argv == NULL) return 1; + child->argv[argc-1]=str; + child->argv[argc]=NULL; + for (s = dest->data; s && *s; s++,str++) { + if (*s == '\\') s++; + *str = *s; + } + *str = '\0'; +#endif +#ifndef __U_BOOT__ + } + gr = xglob(dest, flags, glob_target); + if (gr != 0) return 1; +#endif + + b_reset(dest); +#ifndef __U_BOOT__ + if (ctx->pending_redirect) { + ctx->pending_redirect=NULL; + if (glob_target->gl_pathc != 1) { + error_msg("ambiguous redirect"); + return 1; + } + } else { + child->argv = glob_target->gl_pathv; + } +#endif + if (ctx->w == RES_FOR) { + done_word(dest,ctx); + done_pipe(ctx,PIPE_SEQ); + } + return 0; +} + +/* The only possible error here is out of memory, in which case + * xmalloc exits. */ +static int done_command(struct p_context *ctx) +{ + /* The child is really already in the pipe structure, so + * advance the pipe counter and make a new, null child. + * Only real trickiness here is that the uncommitted + * child structure, to which ctx->child points, is not + * counted in pi->num_progs. */ + struct pipe *pi=ctx->pipe; + struct child_prog *prog=ctx->child; + + if (prog && prog->group == NULL + && prog->argv == NULL +#ifndef __U_BOOT__ + && prog->redirects == NULL) { +#else + ) { +#endif + debug_printf("done_command: skipping null command\n"); + return 0; + } else if (prog) { + pi->num_progs++; + debug_printf("done_command: num_progs incremented to %d\n",pi->num_progs); + } else { + debug_printf("done_command: initializing\n"); + } + pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1)); + + prog = pi->progs + pi->num_progs; +#ifndef __U_BOOT__ + prog->redirects = NULL; +#endif + prog->argv = NULL; +#ifndef __U_BOOT__ + prog->is_stopped = 0; +#endif + prog->group = NULL; +#ifndef __U_BOOT__ + prog->glob_result.gl_pathv = NULL; + prog->family = pi; +#endif + prog->sp = 0; + ctx->child = prog; + prog->type = ctx->type; + + /* but ctx->pipe and ctx->list_head remain unchanged */ + return 0; +} + +static int done_pipe(struct p_context *ctx, pipe_style type) +{ + struct pipe *new_p; + done_command(ctx); /* implicit closure of previous command */ + debug_printf("done_pipe, type %d\n", type); + ctx->pipe->followup = type; + ctx->pipe->r_mode = ctx->w; + new_p=new_pipe(); + ctx->pipe->next = new_p; + ctx->pipe = new_p; + ctx->child = NULL; + done_command(ctx); /* set up new pipe to accept commands */ + return 0; +} + +#ifndef __U_BOOT__ +/* peek ahead in the in_str to find out if we have a "&n" construct, + * as in "2>&1", that represents duplicating a file descriptor. + * returns either -2 (syntax error), -1 (no &), or the number found. + */ +static int redirect_dup_num(struct in_str *input) +{ + int ch, d=0, ok=0; + ch = b_peek(input); + if (ch != '&') return -1; + + b_getch(input); /* get the & */ + ch=b_peek(input); + if (ch == '-') { + b_getch(input); + return -3; /* "-" represents "close me" */ + } + while (isdigit(ch)) { + d = d*10+(ch-'0'); + ok=1; + b_getch(input); + ch = b_peek(input); + } + if (ok) return d; + + error_msg("ambiguous redirect"); + return -2; +} + +/* If a redirect is immediately preceded by a number, that number is + * supposed to tell which file descriptor to redirect. This routine + * looks for such preceding numbers. In an ideal world this routine + * needs to handle all the following classes of redirects... + * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo + * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo + * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo + * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo + * A -1 output from this program means no valid number was found, so the + * caller should use the appropriate default for this redirection. + */ +static int redirect_opt_num(o_string *o) +{ + int num; + + if (o->length==0) return -1; + for(num=0; num<o->length; num++) { + if (!isdigit(*(o->data+num))) { + return -1; + } + } + /* reuse num (and save an int) */ + num=atoi(o->data); + b_reset(o); + return num; +} + +FILE *generate_stream_from_list(struct pipe *head) +{ + FILE *pf; +#if 1 + int pid, channel[2]; + if (pipe(channel)<0) perror_msg_and_die("pipe"); + pid=fork(); + if (pid<0) { + perror_msg_and_die("fork"); + } else if (pid==0) { + close(channel[0]); + if (channel[1] != 1) { + dup2(channel[1],1); + close(channel[1]); + } +#if 0 +#define SURROGATE "surrogate response" + write(1,SURROGATE,sizeof(SURROGATE)); + _exit(run_list(head)); +#else + _exit(run_list_real(head)); /* leaks memory */ +#endif + } + debug_printf("forked child %d\n",pid); + close(channel[1]); + pf = fdopen(channel[0],"r"); + debug_printf("pipe on FILE *%p\n",pf); +#else + free_pipe_list(head,0); + pf=popen("echo surrogate response","r"); + debug_printf("started fake pipe on FILE *%p\n",pf); +#endif + return pf; +} + +/* this version hacked for testing purposes */ +/* return code is exit status of the process that is run. */ +static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end) +{ + int retcode; + o_string result=NULL_O_STRING; + struct p_context inner; + FILE *p; + struct in_str pipe_str; + initialize_context(&inner); + + /* recursion to generate command */ + retcode = parse_stream(&result, &inner, input, subst_end); + if (retcode != 0) return retcode; /* syntax error or EOF */ + done_word(&result, &inner); + done_pipe(&inner, PIPE_SEQ); + b_free(&result); + + p=generate_stream_from_list(inner.list_head); + if (p==NULL) return 1; + mark_open(fileno(p)); + setup_file_in_str(&pipe_str, p); + + /* now send results of command back into original context */ + retcode = parse_stream(dest, ctx, &pipe_str, '\0'); + /* XXX In case of a syntax error, should we try to kill the child? + * That would be tough to do right, so just read until EOF. */ + if (retcode == 1) { + while (b_getch(&pipe_str)!=EOF) { /* discard */ }; + } + + debug_printf("done reading from pipe, pclose()ing\n"); + /* This is the step that wait()s for the child. Should be pretty + * safe, since we just read an EOF from its stdout. We could try + * to better, by using wait(), and keeping track of background jobs + * at the same time. That would be a lot of work, and contrary + * to the KISS philosophy of this program. */ + mark_closed(fileno(p)); + retcode=pclose(p); + free_pipe_list(inner.list_head,0); + debug_printf("pclosed, retcode=%d\n",retcode); + /* XXX this process fails to trim a single trailing newline */ + return retcode; +} + +static int parse_group(o_string *dest, struct p_context *ctx, + struct in_str *input, int ch) +{ + int rcode, endch=0; + struct p_context sub; + struct child_prog *child = ctx->child; + if (child->argv) { + syntax(); + return 1; /* syntax error, groups and arglists don't mix */ + } + initialize_context(&sub); + switch(ch) { + case '(': endch=')'; child->subshell=1; break; + case '{': endch='}'; break; + default: syntax(); /* really logic error */ + } + rcode=parse_stream(dest,&sub,input,endch); + done_word(dest,&sub); /* finish off the final word in the subcontext */ + done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */ + child->group = sub.list_head; + return rcode; + /* child remains "open", available for possible redirects */ +} +#endif + +/* basically useful version until someone wants to get fancier, + * see the bash man page under "Parameter Expansion" */ +static char *lookup_param(char *src) +{ + char *p=NULL; + if (src) { + p = getenv(src); + if (!p) + p = get_local_var(src); + } + return p; +} + +/* return code: 0 for OK, 1 for syntax error */ +static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) +{ +#ifndef __U_BOOT__ + int i, advance=0; +#else + int advance=0; +#endif +#ifndef __U_BOOT__ + char sep[]=" "; +#endif + int ch = input->peek(input); /* first character after the $ */ + debug_printf("handle_dollar: ch=%c\n",ch); + if (isalpha(ch)) { + b_addchr(dest, SPECIAL_VAR_SYMBOL); + ctx->child->sp++; + while(ch=b_peek(input),isalnum(ch) || ch=='_') { + b_getch(input); + b_addchr(dest,ch); + } + b_addchr(dest, SPECIAL_VAR_SYMBOL); +#ifndef __U_BOOT__ + } else if (isdigit(ch)) { + i = ch-'0'; /* XXX is $0 special? */ + if (i<global_argc) { + parse_string(dest, ctx, global_argv[i]); /* recursion */ + } + advance = 1; +#endif + } else switch (ch) { +#ifndef __U_BOOT__ + case '$': + b_adduint(dest,getpid()); + advance = 1; + break; + case '!': + if (last_bg_pid > 0) b_adduint(dest, last_bg_pid); + advance = 1; + break; +#endif + case '?': + b_adduint(dest,last_return_code); + advance = 1; + break; +#ifndef __U_BOOT__ + case '#': + b_adduint(dest,global_argc ? global_argc-1 : 0); + advance = 1; + break; +#endif + case '{': + b_addchr(dest, SPECIAL_VAR_SYMBOL); + ctx->child->sp++; + b_getch(input); + /* XXX maybe someone will try to escape the '}' */ + while(ch=b_getch(input),ch!=EOF && ch!='}') { + b_addchr(dest,ch); + } + if (ch != '}') { + syntax(); + return 1; + } + b_addchr(dest, SPECIAL_VAR_SYMBOL); + break; +#ifndef __U_BOOT__ + case '(': + b_getch(input); + process_command_subs(dest, ctx, input, ')'); + break; + case '*': + sep[0]=ifs[0]; + for (i=1; i<global_argc; i++) { + parse_string(dest, ctx, global_argv[i]); + if (i+1 < global_argc) parse_string(dest, ctx, sep); + } + break; + case '@': + case '-': + case '_': + /* still unhandled, but should be eventually */ + error_msg("unhandled syntax: $%c",ch); + return 1; + break; +#endif + default: + b_addqchr(dest,'$',dest->quote); + } + /* Eat the character if the flag was set. If the compiler + * is smart enough, we could substitute "b_getch(input);" + * for all the "advance = 1;" above, and also end up with + * a nice size-optimized program. Hah! That'll be the day. + */ + if (advance) b_getch(input); + return 0; +} + +#ifndef __U_BOOT__ +int parse_string(o_string *dest, struct p_context *ctx, const char *src) +{ + struct in_str foo; + setup_string_in_str(&foo, src); + return parse_stream(dest, ctx, &foo, '\0'); +} +#endif + +/* return code is 0 for normal exit, 1 for syntax error */ +int parse_stream(o_string *dest, struct p_context *ctx, + struct in_str *input, int end_trigger) +{ + unsigned int ch, m; +#ifndef __U_BOOT__ + int redir_fd; + redir_type redir_style; +#endif + int next; + + /* Only double-quote state is handled in the state variable dest->quote. + * A single-quote triggers a bypass of the main loop until its mate is + * found. When recursing, quote state is passed in via dest->quote. */ + + debug_printf("parse_stream, end_trigger=%d\n",end_trigger); + while ((ch=b_getch(input))!=EOF) { + m = map[ch]; +#ifdef __U_BOOT__ + if (input->__promptme == 0) return 1; +#endif + next = (ch == '\n') ? 0 : b_peek(input); + debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n", + ch,ch,m,dest->quote); + if (m==0 || ((m==1 || m==2) && dest->quote)) { + b_addqchr(dest, ch, dest->quote); + } else { + if (m==2) { /* unquoted IFS */ + if (done_word(dest, ctx)) { + return 1; + } + /* If we aren't performing a substitution, treat a newline as a + * command separator. */ + if (end_trigger != '\0' && ch=='\n') + done_pipe(ctx,PIPE_SEQ); + } + if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { + debug_printf("leaving parse_stream (triggered)\n"); + return 0; + } +#if 0 + if (ch=='\n') { + /* Yahoo! Time to run with it! */ + done_pipe(ctx,PIPE_SEQ); + run_list(ctx->list_head); + initialize_context(ctx); + } +#endif + if (m!=2) switch (ch) { + case '#': + if (dest->length == 0 && !dest->quote) { + while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } + } else { + b_addqchr(dest, ch, dest->quote); + } + break; + case '\\': + if (next == EOF) { + syntax(); + return 1; + } + b_addqchr(dest, '\\', dest->quote); + b_addqchr(dest, b_getch(input), dest->quote); + break; + case '$': + if (handle_dollar(dest, ctx, input)!=0) return 1; + break; + case '\'': + dest->nonnull = 1; + while(ch=b_getch(input),ch!=EOF && ch!='\'') { +#ifdef __U_BOOT__ + if(input->__promptme == 0) return 1; +#endif + b_addchr(dest,ch); + } + if (ch==EOF) { + syntax(); + return 1; + } + break; + case '"': + dest->nonnull = 1; + dest->quote = !dest->quote; + break; +#ifndef __U_BOOT__ + case '`': + process_command_subs(dest, ctx, input, '`'); + break; + case '>': + redir_fd = redirect_opt_num(dest); + done_word(dest, ctx); + redir_style=REDIRECT_OVERWRITE; + if (next == '>') { + redir_style=REDIRECT_APPEND; + b_getch(input); + } else if (next == '(') { + syntax(); /* until we support >(list) Process Substitution */ + return 1; + } + setup_redirect(ctx, redir_fd, redir_style, input); + break; + case '<': + redir_fd = redirect_opt_num(dest); + done_word(dest, ctx); + redir_style=REDIRECT_INPUT; + if (next == '<') { + redir_style=REDIRECT_HEREIS; + b_getch(input); + } else if (next == '>') { + redir_style=REDIRECT_IO; + b_getch(input); + } else if (next == '(') { + syntax(); /* until we support <(list) Process Substitution */ + return 1; + } + setup_redirect(ctx, redir_fd, redir_style, input); + break; +#endif + case ';': + done_word(dest, ctx); + done_pipe(ctx,PIPE_SEQ); + break; + case '&': + done_word(dest, ctx); + if (next=='&') { + b_getch(input); + done_pipe(ctx,PIPE_AND); + } else { +#ifndef __U_BOOT__ + done_pipe(ctx,PIPE_BG); +#else + syntax_err(); + return 1; +#endif + } + break; + case '|': + done_word(dest, ctx); + if (next=='|') { + b_getch(input); + done_pipe(ctx,PIPE_OR); + } else { + /* we could pick up a file descriptor choice here + * with redirect_opt_num(), but bash doesn't do it. + * "echo foo 2| cat" yields "foo 2". */ +#ifndef __U_BOOT__ + done_command(ctx); +#else + syntax_err(); + return 1; +#endif + } + break; +#ifndef __U_BOOT__ + case '(': + case '{': + if (parse_group(dest, ctx, input, ch)!=0) return 1; + break; + case ')': + case '}': + syntax(); /* Proper use of this character caught by end_trigger */ + return 1; + break; +#endif + default: + syntax(); /* this is really an internal logic error */ + return 1; + } + } + } + /* complain if quote? No, maybe we just finished a command substitution + * that was quoted. Example: + * $ echo "`cat foo` plus more" + * and we just got the EOF generated by the subshell that ran "cat foo" + * The only real complaint is if we got an EOF when end_trigger != '\0', + * that is, we were really supposed to get end_trigger, and never got + * one before the EOF. Can't use the standard "syntax error" return code, + * so that parse_stream_outer can distinguish the EOF and exit smoothly. */ + debug_printf("leaving parse_stream (EOF)\n"); + if (end_trigger != '\0') return -1; + return 0; +} + +void mapset(const unsigned char *set, int code) +{ + const unsigned char *s; + for (s=set; *s; s++) map[*s] = code; +} + +void update_ifs_map(void) +{ + /* char *ifs and char map[256] are both globals. */ + ifs = getenv("IFS"); + if (ifs == NULL) ifs=" \t\n"; + /* Precompute a list of 'flow through' behavior so it can be treated + * quickly up front. Computation is necessary because of IFS. + * Special case handling of IFS == " \t\n" is not implemented. + * The map[] array only really needs two bits each, and on most machines + * that would be faster because of the reduced L1 cache footprint. + */ + memset(map,0,sizeof(map)); /* most characters flow through always */ +#ifndef __U_BOOT__ + mapset("\\$'\"`", 3); /* never flow through */ + mapset("<>;&|(){}#", 1); /* flow through if quoted */ +#else + mapset("\\$'\"", 3); /* never flow through */ + mapset(";&|#", 1); /* flow through if quoted */ +#endif + mapset(ifs, 2); /* also flow through if quoted */ +} + +/* most recursion does not come through here, the exeception is + * from builtin_source() */ +int parse_stream_outer(struct in_str *inp, int flag) +{ + + struct p_context ctx; + o_string temp=NULL_O_STRING; + int rcode; +#ifdef __U_BOOT__ + int code = 0; +#endif + do { + ctx.type = flag; + initialize_context(&ctx); + update_ifs_map(); + if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset(";$&|", 0); + inp->promptmode=1; + rcode = parse_stream(&temp, &ctx, inp, '\n'); +#ifdef __U_BOOT__ + if (rcode == 1) flag_repeat = 0; +#endif + if (rcode != 1 && ctx.old_flag != 0) { + syntax(); +#ifdef __U_BOOT__ + flag_repeat = 0; +#endif + } + if (rcode != 1 && ctx.old_flag == 0) { + done_word(&temp, &ctx); + done_pipe(&ctx,PIPE_SEQ); +#ifndef __U_BOOT__ + run_list(ctx.list_head); +#else + if (((code = run_list(ctx.list_head)) == -1)) + flag_repeat = 0; +#endif + } else { + if (ctx.old_flag != 0) { + free(ctx.stack); + b_reset(&temp); + } +#ifdef __U_BOOT__ + if (inp->__promptme == 0) printf("<INTERRUPT>\n"); + inp->__promptme = 1; +#endif + temp.nonnull = 0; + temp.quote = 0; + inp->p = NULL; + free_pipe_list(ctx.list_head,0); + } + b_free(&temp); + } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */ +#ifndef __U_BOOT__ + return 0; +#else + return (code != 0) ? 1 : 0; +#endif /* __U_BOOT__ */ +} + +#ifndef __U_BOOT__ +static int parse_string_outer(const char *s, int flag) +#else +int parse_string_outer(char *s, int flag) +#endif /* __U_BOOT__ */ +{ + struct in_str input; +#ifdef __U_BOOT__ + char *p = NULL; + int rcode; + if ( !s || !*s) + return 1; + if (!(p = strchr(s, '\n')) || *++p) { + p = xmalloc(strlen(s) + 2); + strcpy(p, s); + strcat(p, "\n"); + setup_string_in_str(&input, p); + rcode = parse_stream_outer(&input, flag); + free(p); + return rcode; + } else { +#endif + setup_string_in_str(&input, s); + return parse_stream_outer(&input, flag); +#ifdef __U_BOOT__ + } +#endif +} + +#ifndef __U_BOOT__ +static int parse_file_outer(FILE *f) +#else +int parse_file_outer(void) +#endif +{ + int rcode; + struct in_str input; +#ifndef __U_BOOT__ + setup_file_in_str(&input, f); +#else + setup_file_in_str(&input); +#endif + rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON); + return rcode; +} + +#ifdef __U_BOOT__ +int u_boot_hush_start(void) +{ + top_vars = malloc(sizeof(struct variables)); + top_vars->name = "HUSH_VERSION"; + top_vars->value = "0.01"; + top_vars->next = 0; + top_vars->flg_export = 0; + top_vars->flg_read_only = 1; + return 0; +} + +static void *xmalloc(size_t size) +{ + void *p = NULL; + + if (!(p = malloc(size))) { + printf("ERROR : memory not allocated\n"); + for(;;); + } + return p; +} + +static void *xrealloc(void *ptr, size_t size) +{ + void *p = NULL; + + if (!(p = realloc(ptr, size))) { + printf("ERROR : memory not allocated\n"); + for(;;); + } + return p; +} +#endif /* __U_BOOT__ */ + +#ifndef __U_BOOT__ +/* Make sure we have a controlling tty. If we get started under a job + * aware app (like bash for example), make sure we are now in charge so + * we don't fight over who gets the foreground */ +static void setup_job_control() +{ + static pid_t shell_pgrp; + /* Loop until we are in the foreground. */ + while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ())) + kill (- shell_pgrp, SIGTTIN); + + /* Ignore interactive and job-control signals. */ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + + /* Put ourselves in our own process group. */ + setsid(); + shell_pgrp = getpid (); + setpgid (shell_pgrp, shell_pgrp); + + /* Grab control of the terminal. */ + tcsetpgrp(shell_terminal, shell_pgrp); +} + +int hush_main(int argc, char **argv) +{ + int opt; + FILE *input; + char **e = environ; + + /* XXX what should these be while sourcing /etc/profile? */ + global_argc = argc; + global_argv = argv; + + /* (re?) initialize globals. Sometimes hush_main() ends up calling + * hush_main(), therefore we cannot rely on the BSS to zero out this + * stuff. Reset these to 0 every time. */ + ifs = NULL; + /* map[] is taken care of with call to update_ifs_map() */ + fake_mode = 0; + interactive = 0; + close_me_head = NULL; + last_bg_pid = 0; + job_list = NULL; + last_jobid = 0; + + /* Initialize some more globals to non-zero values */ + set_cwd(); +#ifdef BB_FEATURE_COMMAND_EDITING + cmdedit_set_initial_prompt(); +#else + PS1 = NULL; +#endif + PS2 = "> "; + + /* initialize our shell local variables with the values + * currently living in the environment */ + if (e) { + for (; *e; e++) + set_local_var(*e, 2); /* without call putenv() */ + } + + last_return_code=EXIT_SUCCESS; + + + if (argv[0] && argv[0][0] == '-') { + debug_printf("\nsourcing /etc/profile\n"); + if ((input = fopen("/etc/profile", "r")) != NULL) { + mark_open(fileno(input)); + parse_file_outer(input); + mark_closed(fileno(input)); + fclose(input); + } + } + input=stdin; + + while ((opt = getopt(argc, argv, "c:xif")) > 0) { + switch (opt) { + case 'c': + { + global_argv = argv+optind; + global_argc = argc-optind; + opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON); + goto final_return; + } + break; + case 'i': + interactive++; + break; + case 'f': + fake_mode++; + break; + default: +#ifndef BB_VER + fprintf(stderr, "Usage: sh [FILE]...\n" + " or: sh -c command [args]...\n\n"); + exit(EXIT_FAILURE); +#else + show_usage(); +#endif + } + } + /* A shell is interactive if the `-i' flag was given, or if all of + * the following conditions are met: + * no -c command + * no arguments remaining or the -s flag given + * standard input is a terminal + * standard output is a terminal + * Refer to Posix.2, the description of the `sh' utility. */ + if (argv[optind]==NULL && input==stdin && + isatty(fileno(stdin)) && isatty(fileno(stdout))) { + interactive++; + } + + debug_printf("\ninteractive=%d\n", interactive); + if (interactive) { + /* Looks like they want an interactive shell */ + fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); + setup_job_control(); + } + + if (argv[optind]==NULL) { + opt=parse_file_outer(stdin); + goto final_return; + } + + debug_printf("\nrunning script '%s'\n", argv[optind]); + global_argv = argv+optind; + global_argc = argc-optind; + input = xfopen(argv[optind], "r"); + opt = parse_file_outer(input); + +#ifdef BB_FEATURE_CLEAN_UP + fclose(input); + if (cwd && cwd != unknown) + free((char*)cwd); + { + struct variables *cur, *tmp; + for(cur = top_vars; cur; cur = tmp) { + tmp = cur->next; + if (!cur->flg_read_only) { + free(cur->name); + free(cur->value); + free(cur); + } + } + } +#endif + +final_return: + return(opt?opt:last_return_code); +} +#endif + +static char *insert_var_value(char *inp) +{ + int res_str_len = 0; + int len; + int done = 0; + char *p, *p1, *res_str = NULL; + + while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { + if (p != inp) { + len = p - inp; + res_str = xrealloc(res_str, (res_str_len + len)); + strncpy((res_str + res_str_len), inp, len); + res_str_len += len; + } + inp = ++p; + p = strchr(inp, SPECIAL_VAR_SYMBOL); + *p = '\0'; + if ((p1 = lookup_param(inp))) { + len = res_str_len + strlen(p1); + res_str = xrealloc(res_str, (1 + len)); + strcpy((res_str + res_str_len), p1); + res_str_len = len; + } + *p = SPECIAL_VAR_SYMBOL; + inp = ++p; + done = 1; + } + if (done) { + res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp))); + strcpy((res_str + res_str_len), inp); + while ((p = strchr(res_str, '\n'))) { + *p = ' '; + } + } + return (res_str == NULL) ? inp : res_str; +} + +static char **make_list_in(char **inp, char *name) +{ + int len, i; + int name_len = strlen(name); + int n = 0; + char **list; + char *p1, *p2, *p3; + + /* create list of variable values */ + list = xmalloc(sizeof(*list)); + for (i = 0; inp[i]; i++) { + p3 = insert_var_value(inp[i]); + p1 = p3; + while (*p1) { + if ((*p1 == ' ')) { + p1++; + continue; + } + if ((p2 = strchr(p1, ' '))) { + len = p2 - p1; + } else { + len = strlen(p1); + p2 = p1 + len; + } + /* we use n + 2 in realloc for list,because we add + * new element and then we will add NULL element */ + list = xrealloc(list, sizeof(*list) * (n + 2)); + list[n] = xmalloc(2 + name_len + len); + strcpy(list[n], name); + strcat(list[n], "="); + strncat(list[n], p1, len); + list[n++][name_len + len + 1] = '\0'; + p1 = p2; + } + if (p3 != inp[i]) free(p3); + } + list[n] = NULL; + return list; +} + +/* Make new string for parser */ +static char * make_string(char ** inp) +{ + char *p; + char *str = NULL; + int n; + int len = 2; + + for (n = 0; inp[n]; n++) { + p = insert_var_value(inp[n]); + str = xrealloc(str, (len + strlen(p))); + if (n) { + strcat(str, " "); + } else { + *str = '\0'; + } + strcat(str, p); + len = strlen(str) + 3; + if (p != inp[n]) free(p); + } + len = strlen(str); + *(str + len) = '\n'; + *(str + len + 1) = '\0'; + return str; +} + +#endif /* CFG_HUSH_PARSER */ +/****************************************************************************/ diff --git a/cpu/74xx_7xx/cache.S b/cpu/74xx_7xx/cache.S new file mode 100644 index 0000000..f35966c --- /dev/null +++ b/cpu/74xx_7xx/cache.S @@ -0,0 +1,381 @@ +#include <config.h> +#include <mpc74xx.h> +#include <version.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#ifndef CACHE_LINE_SIZE +# define CACHE_LINE_SIZE L1_CACHE_BYTES +#endif + +#if CACHE_LINE_SIZE == 128 +#define LG_CACHE_LINE_SIZE 7 +#elif CACHE_LINE_SIZE == 32 +#define LG_CACHE_LINE_SIZE 5 +#elif CACHE_LINE_SIZE == 16 +#define LG_CACHE_LINE_SIZE 4 +#elif CACHE_LINE_SIZE == 8 +#define LG_CACHE_LINE_SIZE 3 +#else +# error "Invalid cache line size!" +#endif + +/* + * Invalidate L1 instruction cache. + */ +_GLOBAL(invalidate_l1_instruction_cache) + mfspr r3,PVR + rlwinm r3,r3,16,16,31 + cmpi 0,r3,1 + beqlr /* for 601, do nothing */ + /* 603/604 processor - use invalidate-all bit in HID0 */ + mfspr r3,HID0 + ori r3,r3,HID0_ICFI + mtspr HID0,r3 + isync + blr + +/* + * Invalidate L1 data cache. + */ +_GLOBAL(invalidate_l1_data_cache) + mfspr r3,HID0 + ori r3,r3,HID0_DCFI + mtspr HID0,r3 + isync + blr + +/* + * Flush data cache. + */ +_GLOBAL(flush_data_cache) + lis r3,0 + lis r5,CACHE_LINE_SIZE +flush: + cmp 0,1,r3,r5 + bge done + lwz r5,0(r3) + lis r5,CACHE_LINE_SIZE + addi r3,r3,0x4 + b flush +done: + blr +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * This is a no-op on the 601. + * + * flush_icache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_icache_range) + mfspr r5,PVR + rlwinm r5,r5,16,16,31 + cmpi 0,r5,1 + beqlr /* for 601, do nothing */ + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: icbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 2b + sync /* additional sync needed on g4 */ + isync + blr +/* + * Write any modified data cache blocks out to memory. + * Does not invalidate the corresponding cache lines (especially for + * any corresponding instruction cache). + * + * clean_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(clean_dcache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 /* align r3 down to cache line */ + subf r4,r3,r4 /* r4 = offset of stop from start of cache line */ + add r4,r4,r5 /* r4 += cache_line_size-1 */ + srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */ + beqlr /* if r4 == 0 return */ + mtctr r4 /* ctr = r4 */ + + sync +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + blr + +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * + * flush_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_dcache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + + sync +1: dcbf 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbf's to get to ram */ + blr + +/* + * Like above, but invalidate the D-cache. This is used by the 8xx + * to invalidate the cache so the PPC core doesn't get stale data + * from the CPM (no cache snooping here :-). + * + * invalidate_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(invalidate_dcache_range) + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + + sync +1: dcbi 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbi's to get to ram */ + blr + +/* + * Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * This is a no-op on the 601 which has a unified cache. + * + * void __flush_page_to_ram(void *page) + */ +_GLOBAL(__flush_page_to_ram) + mfspr r5,PVR + rlwinm r5,r5,16,16,31 + cmpi 0,r5,1 + beqlr /* for 601, do nothing */ + rlwinm r3,r3,0,0,19 /* Get page base address */ + li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */ + mtctr r4 + mr r6,r3 +0: dcbst 0,r3 /* Write line to ram */ + addi r3,r3,CACHE_LINE_SIZE + bdnz 0b + sync + mtctr r4 +1: icbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 1b + sync + isync + blr + +/* + * Flush a particular page from the instruction cache. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * This is a no-op on the 601 which has a unified cache. + * + * void __flush_icache_page(void *page) + */ +_GLOBAL(__flush_icache_page) + mfspr r5,PVR + rlwinm r5,r5,16,16,31 + cmpi 0,r5,1 + beqlr /* for 601, do nothing */ + li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */ + mtctr r4 +1: icbi 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync + isync + blr + +/* + * Clear a page using the dcbz instruction, which doesn't cause any + * memory traffic (except to write out any cache lines which get + * displaced). This only works on cacheable memory. + */ +_GLOBAL(clear_page) + li r0,4096/CACHE_LINE_SIZE + mtctr r0 +1: dcbz 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + blr + +/* + * Enable L1 Instruction cache + */ +_GLOBAL(icache_enable) + mfspr r3, HID0 + li r5, HID0_ICFI|HID0_ILOCK + andc r3, r3, r5 + ori r3, r3, HID0_ICE + ori r5, r3, HID0_ICFI + mtspr HID0, r5 + mtspr HID0, r3 + isync + blr + +/* + * Disable L1 Instruction cache + */ +_GLOBAL(icache_disable) + mfspr r3, HID0 + li r5, 0 + ori r5, r5, HID0_ICE + andc r3, r3, r5 + mtspr HID0, r3 + isync + blr + +/* + * Is instruction cache enabled? + */ +_GLOBAL(icache_status) + mfspr r3, HID0 + andi. r3, r3, HID0_ICE + blr + + +_GLOBAL(l1dcache_enable) + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + ori r3, r3, HID0_DCE + ori r5, r3, HID0_DCFI + mtspr HID0, r5 /* enable + invalidate */ + mtspr HID0, r3 /* enable */ + sync + blr + +/* + * Enable data cache(s) - L1 and optionally L2 + * Calls l2cache_enable. LR saved in r5 + */ +_GLOBAL(dcache_enable) + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + ori r3, r3, HID0_DCE + ori r5, r3, HID0_DCFI + mtspr HID0, r5 /* enable + invalidate */ + mtspr HID0, r3 /* enable */ + sync +#ifdef CFG_L2 + mflr r5 + bl l2cache_enable /* uses r3 and r4 */ + sync + mtlr r5 +#endif + blr + + +/* + * Disable data cache(s) - L1 and optionally L2 + * Calls flush_data_cache and l2cache_disable_no_flush. + * LR saved in r4 + */ +_GLOBAL(dcache_disable) + mflr r4 /* save link register */ + bl flush_data_cache /* uses r3 and r5 */ + sync + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + li r5, HID0_DCE|HID0_DCFI + andc r3, r3, r5 /* no enable, no invalidate */ + mtspr HID0, r3 + sync +#ifdef CFG_L2 + bl l2cache_disable_no_flush /* uses r3 */ +#endif + mtlr r4 /* restore link register */ + blr + +/* + * Is data cache enabled? + */ +_GLOBAL(dcache_status) + mfspr r3, HID0 + andi. r3, r3, HID0_DCE + blr + +/* + * Invalidate L2 cache using L2I and polling L2IP + */ +_GLOBAL(l2cache_invalidate) + sync + oris r3, r3, L2CR_L2I@h + sync + mtspr l2cr, r3 + sync +invl2: + mfspr r3, l2cr + andi. r3, r3, L2CR_L2IP + bne invl2 + /* turn off the global invalidate bit */ + mfspr r3, l2cr + rlwinm r3, r3, 0, 11, 9 + sync + mtspr l2cr, r3 + sync + blr + +/* + * Enable L2 cache + * Calls l2cache_invalidate. LR is saved in r4 + */ +_GLOBAL(l2cache_enable) + mflr r4 /* save link register */ + bl l2cache_invalidate /* uses r3 */ + sync + lis r3, L2_ENABLE@h + ori r3, r3, L2_ENABLE@l + mtspr l2cr, r3 + isync + mtlr r4 /* restore link register */ + blr + +/* + * Disable L2 cache + * Calls flush_data_cache. LR is saved in r4 + */ +_GLOBAL(l2cache_disable) + mflr r4 /* save link register */ + bl flush_data_cache /* uses r3 and r5 */ + sync + mtlr r4 /* restore link register */ +l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */ + lis r3, L2_INIT@h + ori r3, r3, L2_INIT@l + mtspr l2cr, r3 + isync + blr diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S new file mode 100644 index 0000000..e9899a9 --- /dev/null +++ b/cpu/arm720t/start.S @@ -0,0 +1,429 @@ +/* + * armboot - Startup Code for ARM720 CPU-core + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +/* + * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h) + */ +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * Note: _armboot_end_data and _armboot_end are defined + * by the (board-dependent) linker script. + * _armboot_end_data is the first usable FLASH address after armboot + */ +.globl _armboot_end_data +_armboot_end_data: + .word armboot_end_data +.globl _armboot_end +_armboot_end: + .word armboot_end + +/* + * _armboot_real_end is the first usable RAM address behind armboot + * and the various stacks + */ +.globl _armboot_real_end +_armboot_real_end: + .word 0x0badc0de + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de +#endif + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifdef CONFIG_INIT_CRITICAL + bl cpu_init_crit +#endif + +relocate: + /* + * relocate armboot to RAM + */ + adr r0, _start /* r0 <- current position of code */ + ldr r2, _armboot_start + ldr r3, _armboot_end + sub r2, r3, r2 /* r2 <- size of armboot */ + ldr r1, _TEXT_BASE /* r1 <- destination address */ + add r2, r0, r2 /* r2 <- source end address */ + + /* + * r0 = source address + * r1 = target address + * r2 = source end address + */ +copy_loop: + ldmia r0!, {r3-r10} + stmia r1!, {r3-r10} + cmp r0, r2 + ble copy_loop + + /* set up the stack */ + ldr r0, _armboot_end + add r0, r0, #CONFIG_STACKSIZE + sub sp, r0, #12 /* leave 3 words for abort-stack */ + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +/* Interupt-Controller base addresses */ +INTMR1: .word 0x80000280 @ 32 bit size +INTMR2: .word 0x80001280 @ 16 bit size +INTMR3: .word 0x80002280 @ 8 bit size + +/* SYSCONs */ +SYSCON1: .word 0x80000100 +SYSCON2: .word 0x80001100 +SYSCON3: .word 0x80002200 + +#define CLKCTL 0x6 /* mask */ +#define CLKCTL_18 0x0 /* 18.432 MHz */ +#define CLKCTL_36 0x2 /* 36.864 MHz */ +#define CLKCTL_49 0x4 /* 49.152 MHz */ +#define CLKCTL_73 0x6 /* 73.728 MHz */ + +cpu_init_crit: + /* + * mask all IRQs by clearing all bits in the INTMRs + */ + mov r1, #0x00 + ldr r0, INTMR1 + str r1, [r0] + ldr r0, INTMR2 + str r1, [r0] + ldr r0, INTMR3 + str r1, [r0] + + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15,0,r0,c1,c0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + mcr p15,0,r0,c1,c0 + +#ifdef CONFIG_ARM7_REVD + /* set clock speed */ + /* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */ + /* !!! not doing DRAM refresh properly! */ + ldr r0, SYSCON3 + ldr r1, [r0] + bic r1, r1, #CLKCTL + orr r1, r1, #CLKCTL_36 + str r1, [r0] +#endif + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a memsetup.S in your board directory. + */ + mov ip, lr + bl memsetup + mov lr, ip + + mov pc, lr + + + + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + + ldr r2, _armboot_end + add r2, r2, #CONFIG_STACKSIZE + sub r2, r2, #8 + ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + .endm + + .macro irq_restore_user_regs + ldmia sp, {r0 - lr}^ @ Calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 @ return & move spsr_svc into cpsr + .endm + + .macro get_bad_stack + ldr r13, _armboot_end @ setup our mode stack + add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack + sub r13, r13, #8 + + str lr, [r13] @ save caller lr / spsr + mrs lr, spsr + str lr, [r13, #4] + + mov r13, #MODE_SVC @ prepare SVC-Mode + msr spsr_c, r13 + mov lr, pc + movs pc, lr + .endm + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + +#ifdef CONFIG_USE_IRQ + + .align 5 +irq: + get_irq_stack + irq_save_user_regs + bl do_irq + irq_restore_user_regs + + .align 5 +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + irq_restore_user_regs + +#else + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq + +#endif + + .align 5 +.globl reset_cpu +reset_cpu: + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S new file mode 100644 index 0000000..a858dfa --- /dev/null +++ b/cpu/arm920t/start.S @@ -0,0 +1,475 @@ +/* + * armboot - Startup Code for ARM920 CPU-core + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +/* + * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h) + */ +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * Note: _armboot_end_data and _armboot_end are defined + * by the (board-dependent) linker script. + * _armboot_end_data is the first usable FLASH address after armboot + */ +.globl _armboot_end_data +_armboot_end_data: + .word armboot_end_data +.globl _armboot_end +_armboot_end: + .word armboot_end + +/* + * _armboot_real_end is the first usable RAM address behind armboot + * and the various stacks + */ +.globl _armboot_real_end +_armboot_real_end: + .word 0x0badc0de + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de +#endif + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + +/* turn off the watchdog */ +#if defined(CONFIG_S3C2400) +#define pWTCON 0x15300000 +/* Interupt-Controller base addresses */ +#define INTMSK 0x14400008 +/* clock divisor register */ +#define CLKDIVN 0x14800014 +#elif defined(CONFIG_S3C2410) +#define pWTCON 0x53000000 +/* Interupt-Controller base addresses */ +#define INTMSK 0x4A000008 +#define INTSUBMSK 0x4A00001C +/* clock divisor register */ +#define CLKDIVN 0x4C000014 +#endif + + ldr r0, =pWTCON + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =INTMSK + str r1, [r0] +#if defined(CONFIG_S3C2410) + ldr r1, =0x3ff + ldr r0, =INTSUBMSK + str r1, [r0] +#endif + + /* FCLK:HCLK:PCLK = 1:2:4 */ + /* default FCLK is 120 MHz ! */ + ldr r0, =CLKDIVN + mov r1, #3 + str r1, [r0] + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifdef CONFIG_INIT_CRITICAL + bl cpu_init_crit +#endif + +relocate: + /* + * relocate armboot to RAM + */ + adr r0, _start /* r0 <- current position of code */ + ldr r2, _armboot_start + ldr r3, _armboot_end + sub r2, r3, r2 /* r2 <- size of armboot */ + ldr r1, _TEXT_BASE /* r1 <- destination address */ + add r2, r0, r2 /* r2 <- source end address */ + + /* + * r0 = source address + * r1 = target address + * r2 = source end address + */ +copy_loop: + ldmia r0!, {r3-r10} + stmia r1!, {r3-r10} + cmp r0, r2 + ble copy_loop + +#if 0 + /* try doing this stuff after the relocation */ + ldr r0, =pWTCON + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =INTMR + str r1, [r0] + + /* FCLK:HCLK:PCLK = 1:2:4 */ + /* default FCLK is 120 MHz ! */ + ldr r0, =CLKDIVN + mov r1, #3 + str r1, [r0] + /* END stuff after relocation */ +#endif + + /* set up the stack */ + ldr r0, _armboot_end + add r0, r0, #CONFIG_STACKSIZE + sub sp, r0, #12 /* leave 3 words for abort-stack */ + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + mcr p15, 0, r0, c1, c0, 0 + + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a memsetup.S in your board directory. + */ + mov ip, lr + bl memsetup + mov lr, ip + + mov pc, lr + + + + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + + ldr r2, _armboot_end + add r2, r2, #CONFIG_STACKSIZE + sub r2, r2, #8 + ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + .endm + + .macro irq_restore_user_regs + ldmia sp, {r0 - lr}^ @ Calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 @ return & move spsr_svc into cpsr + .endm + + .macro get_bad_stack + ldr r13, _armboot_end @ setup our mode stack + add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack + sub r13, r13, #8 + + str lr, [r13] @ save caller lr / spsr + mrs lr, spsr + str lr, [r13, #4] + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 + mov lr, pc + movs pc, lr + .endm + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + +#ifdef CONFIG_USE_IRQ + + .align 5 +irq: + get_irq_stack + irq_save_user_regs + bl do_irq + irq_restore_user_regs + + .align 5 +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + irq_restore_user_regs + +#else + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq + +#endif + + .align 5 +.globl reset_cpu +reset_cpu: +#ifdef CONFIG_S3C2400 + bl disable_interrupts + ldr r1, _rWTCON + ldr r2, _rWTCNT + /* Disable watchdog */ + mov r3, #0x0000 + str r3, [r1] + /* Initialize watchdog timer count register */ + mov r3, #0x0001 + str r3, [r2] + /* Enable watchdog timer; assert reset at timer timeout */ + mov r3, #0x0021 + str r3, [r1] +_loop_forever: + b _loop_forever +_rWTCON: + .word 0x15300000 +_rWTCNT: + .word 0x15300008 +#else /* ! CONFIG_S3C2400 */ + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 +#endif /* CONFIG_S3C2400 */ diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c new file mode 100644 index 0000000..ff164fe --- /dev/null +++ b/cpu/mpc8260/ether_scc.c @@ -0,0 +1,358 @@ +/* + * MPC8260 SCC Ethernet + * + * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) + * + * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright (c) 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/cpm_8260.h> +#include <mpc8260.h> +#include <net.h> +#include <command.h> +#include <config.h> + +#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_COMMANDS & CFG_CMD_NET) + +#if (CONFIG_ETHER_INDEX == 1) +# define PROFF_ENET PROFF_SCC1 +# define CPM_CR_ENET_PAGE CPM_CR_SCC1_PAGE +# define CPM_CR_ENET_SBLOCK CPM_CR_SCC1_SBLOCK +# define CMXSCR_MASK (CMXSCR_SC1 |\ + CMXSCR_RS1CS_MSK |\ + CMXSCR_TS1CS_MSK) + +#elif (CONFIG_ETHER_INDEX == 2) +# define PROFF_ENET PROFF_SCC2 +# define CPM_CR_ENET_PAGE CPM_CR_SCC2_PAGE +# define CPM_CR_ENET_SBLOCK CPM_CR_SCC2_SBLOCK +# define CMXSCR_MASK (CMXSCR_SC2 |\ + CMXSCR_RS2CS_MSK |\ + CMXSCR_TS2CS_MSK) + +#elif (CONFIG_ETHER_INDEX == 3) +# define PROFF_ENET PROFF_SCC3 +# define CPM_CR_ENET_PAGE CPM_CR_SCC3_PAGE +# define CPM_CR_ENET_SBLOCK CPM_CR_SCC3_SBLOCK +# define CMXSCR_MASK (CMXSCR_SC3 |\ + CMXSCR_RS3CS_MSK |\ + CMXSCR_TS3CS_MSK) +#elif (CONFIG_ETHER_INDEX == 4) +# define PROFF_ENET PROFF_SCC4 +# define CPM_CR_ENET_PAGE CPM_CR_SCC4_PAGE +# define CPM_CR_ENET_SBLOCK CPM_CR_SCC4_SBLOCK +# define CMXSCR_MASK (CMXSCR_SC4 |\ + CMXSCR_RS4CS_MSK |\ + CMXSCR_TS4CS_MSK) + +#endif + + +/* Ethernet Transmit and Receive Buffers */ +#define DBUF_LENGTH 1520 + +#define TX_BUF_CNT 2 + +#define TOUT_LOOP 1000000 + +static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ]; + +static uint rxIdx; /* index of the current RX buffer */ +static uint txIdx; /* index of the current TX buffer */ + +/* + * SCC Ethernet Tx and Rx buffer descriptors allocated at the + * immr->udata_bd address on Dual-Port RAM + * Provide for Double Buffering + */ + +typedef volatile struct CommonBufferDescriptor { + cbd_t rxbd[PKTBUFSRX]; /* Rx BD */ + cbd_t txbd[TX_BUF_CNT]; /* Tx BD */ +} RTXBD; + +static RTXBD *rtx; + + +int eth_send(volatile void *packet, int length) +{ + int i; + int result = 0; + + if (length <= 0) { + printf("scc: bad packet size: %d\n", length); + goto out; + } + + for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) { + if (i >= TOUT_LOOP) { + printf("scc: tx buffer not ready\n"); + goto out; + } + } + + rtx->txbd[txIdx].cbd_bufaddr = (uint)packet; + rtx->txbd[txIdx].cbd_datlen = length; + rtx->txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST | + BD_ENET_TX_WRAP); + + for(i=0; rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY; i++) { + if (i >= TOUT_LOOP) { + printf("scc: tx error\n"); + goto out; + } + } + + /* return only status bits */ + result = rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS; + + out: + return result; +} + + +int eth_rx(void) +{ + int length; + + for (;;) + { + if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { + length = -1; + break; /* nothing received - leave for() loop */ + } + + length = rtx->rxbd[rxIdx].cbd_datlen; + + if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) + { + printf("err: %x\n", rtx->rxbd[rxIdx].cbd_sc); + } + else + { + /* Pass the packet up to the protocol layers. */ + NetReceive(NetRxPackets[rxIdx], length - 4); + } + + + /* Give the buffer back to the SCC. */ + rtx->rxbd[rxIdx].cbd_datlen = 0; + + /* wrap around buffer index when necessary */ + if ((rxIdx + 1) >= PKTBUFSRX) { + rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | + BD_ENET_RX_EMPTY); + rxIdx = 0; + } + else { + rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; + rxIdx++; + } + } + return length; +} + +/************************************************************** + * + * SCC Ethernet Initialization Routine + * + *************************************************************/ + +int eth_init(bd_t *bis) +{ + int i; + volatile immap_t *immr = (immap_t *)CFG_IMMR; + scc_enet_t *pram_ptr; + uint dpaddr; + + rxIdx = 0; + txIdx = 0; + + /* assign static pointer to BD area */ + dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16); + rtx = (RTXBD *)&immr->im_dprambase[dpaddr]; + + /* 24.21 - (1-3): ioports have been set up already */ + + /* 24.21 - (4,5): connect SCC's tx and rx clocks, use NMSI for SCC */ + immr->im_cpmux.cmx_uar = 0; + immr->im_cpmux.cmx_scr = ( (immr->im_cpmux.cmx_scr & ~CMXSCR_MASK) | + CFG_CMXSCR_VALUE); + + + /* 24.21 (6) write RBASE and TBASE to parameter RAM */ + pram_ptr = (scc_enet_t *)&(immr->im_dprambase[PROFF_ENET]); + pram_ptr->sen_genscc.scc_rbase = (unsigned int)(&rtx->rxbd[0]); + pram_ptr->sen_genscc.scc_tbase = (unsigned int)(&rtx->txbd[0]); + + pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Nrml Ops and Mot byte ordering */ + pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Nrml access */ + + pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. package len 1520 */ + + pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */ + pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */ + + + /* 24.21 - (7): Write INIT RX AND TX PARAMETERS to CPCR */ + while(immr->im_cpm.cp_cpcr & CPM_CR_FLG); + immr->im_cpm.cp_cpcr = mk_cr_cmd(CPM_CR_ENET_PAGE, + CPM_CR_ENET_SBLOCK, + 0x0c, + CPM_CR_INIT_TRX) | CPM_CR_FLG; + + /* 24.21 - (8-18): Set up parameter RAM */ + pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */ + pram_ptr->sen_alec = 0x0; /* Align Error Counter (unused) */ + pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */ + + pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */ + + pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */ + + pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */ + pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */ + + pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */ + pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */ + + pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */ + pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */ + pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */ + pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */ + +# define ea bis->bi_enetaddr + pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4]; + pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2]; + pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0]; +# undef ea + + pram_ptr->sen_pper = 0x0; /* Persistence (unused) */ + + pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */ + pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */ + pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */ + pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */ + + pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */ + pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */ + pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */ + + + /* 24.21 - (19): Initialize RxBD */ + for (i = 0; i < PKTBUFSRX; i++) + { + rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; + rtx->rxbd[i].cbd_datlen = 0; /* Reset */ + rtx->rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i]; + } + + rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; + + /* 24.21 - (20): Initialize TxBD */ + for (i = 0; i < TX_BUF_CNT; i++) + { + rtx->txbd[i].cbd_sc = (BD_ENET_TX_PAD | + BD_ENET_TX_LAST | + BD_ENET_TX_TC); + rtx->txbd[i].cbd_datlen = 0; /* Reset */ + rtx->txbd[i].cbd_bufaddr = (uint)&txbuf[i][0]; + } + + rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; + + /* 24.21 - (21): Write 0xffff to SCCE */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_scce = ~(0x0); + + /* 24.21 - (22): Write to SCCM to enable TXE, RXF, TXB events */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_sccm = (SCCE_ENET_TXE | + SCCE_ENET_RXF | + SCCE_ENET_TXB); + + /* 24.21 - (23): we don't use ethernet interrupts */ + + /* 24.21 - (24): Clear GSMR_H to enable normal operations */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrh = 0; + + /* 24.21 - (25): Clear GSMR_L to enable normal operations */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl = (SCC_GSMRL_TCI | + SCC_GSMRL_TPL_48 | + SCC_GSMRL_TPP_10 | + SCC_GSMRL_MODE_ENET); + + /* 24.21 - (26): Initialize DSR */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_dsr = 0xd555; + + /* 24.21 - (27): Initialize PSMR2 + * + * Settings: + * CRC = 32-Bit CCITT + * NIB = Begin searching for SFD 22 bits after RENA + * FDE = Full Duplex Enable + * BRO = Reject broadcast packets + * PROMISCOUS = Catch all packets regardless of dest. MAC adress + */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_psmr = SCC_PSMR_ENCRC | + SCC_PSMR_NIB22 | +#if defined(CONFIG_SCC_ENET_FULL_DUPLEX) + SCC_PSMR_FDE | +#endif +#if defined(CONFIG_SCC_ENET_NO_BROADCAST) + SCC_PSMR_BRO | +#endif +#if defined(CONFIG_SCC_ENET_PROMISCOUS) + SCC_PSMR_PRO | +#endif + 0; + + /* 24.21 - (28): Write to GSMR_L to enable SCC */ + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | + SCC_GSMRL_ENT); + + return 1; +} + + + +void eth_halt(void) +{ + volatile immap_t *immr = (immap_t *)CFG_IMMR; + immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl &= ~(SCC_GSMRL_ENR | + SCC_GSMRL_ENT); +} + +#if 0 +void restart(void) +{ + volatile immap_t *immr = (immap_t *)CFG_IMMR; + immr->im_cpm.cp_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | + SCC_GSMRL_ENT); +} +#endif + +#endif /* CONFIG_ETHER_ON_SCC && CFG_CMD_NET */ + diff --git a/cpu/ppc4xx/kgdb.S b/cpu/ppc4xx/kgdb.S new file mode 100644 index 0000000..78681cd --- /dev/null +++ b/cpu/ppc4xx/kgdb.S @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2000 Murray Jensen <Murray.Jensen@cmst.csiro.au> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <command.h> +#include <ppc4xx.h> +#include <version.h> + +#define CONFIG_405GP 1 /* needed for Linux kernel header files */ +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + /* + * cache flushing routines for kgdb + */ + + .globl kgdb_flush_cache_all +kgdb_flush_cache_all: + /* icache */ + iccci r0,r0 /* iccci invalidates the entire I cache */ + /* dcache */ + addi r6,0,0x0000 /* clear GPR 6 */ + addi r7,r0, 128 /* do loop for # of dcache lines */ + /* NOTE: dccci invalidates both */ + mtctr r7 /* ways in the D cache */ +..dcloop: + dccci 0,r6 /* invalidate line */ + addi r6,r6, 32 /* bump to next line */ + bdnz ..dcloop + blr + + .globl kgdb_flush_cache_range +kgdb_flush_cache_range: + li r5,CFG_CACHELINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,CFG_CACHELINE_SHIFT + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,CFG_CACHELINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: icbi 0,r6 + addi r6,r6,CFG_CACHELINE_SIZE + bdnz 2b + SYNC + blr + +#endif /* CFG_CMD_KGDB */ diff --git a/cpu/ppc4xx/resetvec.S b/cpu/ppc4xx/resetvec.S new file mode 100644 index 0000000..5350225 --- /dev/null +++ b/cpu/ppc4xx/resetvec.S @@ -0,0 +1,10 @@ +/* Copyright MontaVista Software Incorporated, 2000 */ + + + .section .resetvec,"ax" +#if defined(CONFIG_440) + b _start_440 +#else + b _start +#endif + diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c new file mode 100644 index 0000000..d02ff2f --- /dev/null +++ b/cpu/ppc4xx/serial.c @@ -0,0 +1,808 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +/*------------------------------------------------------------------------------+ */ +/* + * This source code has been made available to you by IBM on an AS-IS + * basis. Anyone receiving this source is licensed under IBM + * copyrights to use it in any way he or she deems fit, including + * copying it, modifying it, compiling it, and redistributing it either + * with or without modifications. No license under IBM patents or + * patent applications is to be implied by the copyright license. + * + * Any user of this software should understand that IBM cannot provide + * technical support for this software and will not be responsible for + * any consequences resulting from the use of this software. + * + * Any person who transfers this source code or any derivative work + * must include the IBM copyright notice, this paragraph, and the + * preceding two paragraphs in the transferred software. + * + * COPYRIGHT I B M CORPORATION 1995 + * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + */ +/*------------------------------------------------------------------------------- */ + +#include <common.h> +#include <commproc.h> +#include <asm/processor.h> +#include <watchdog.h> +#include "vecnum.h" + +#if CONFIG_SERIAL_SOFTWARE_FIFO +#include <malloc.h> +#endif + +/*****************************************************************************/ +#ifdef CONFIG_IOP480 + +#define SPU_BASE 0x40000000 + +#define spu_LineStat_rc 0x00 /* Line Status Register (Read/Clear) */ +#define spu_LineStat_w 0x04 /* Line Status Register (Set) */ +#define spu_Handshk_rc 0x08 /* Handshake Status Register (Read/Clear) */ +#define spu_Handshk_w 0x0c /* Handshake Status Register (Set) */ +#define spu_BRateDivh 0x10 /* Baud rate divisor high */ +#define spu_BRateDivl 0x14 /* Baud rate divisor low */ +#define spu_CtlReg 0x18 /* Control Register */ +#define spu_RxCmd 0x1c /* Rx Command Register */ +#define spu_TxCmd 0x20 /* Tx Command Register */ +#define spu_RxBuff 0x24 /* Rx data buffer */ +#define spu_TxBuff 0x24 /* Tx data buffer */ + +/*-----------------------------------------------------------------------------+ + | Line Status Register. + +-----------------------------------------------------------------------------*/ +#define asyncLSRport1 0x40000000 +#define asyncLSRport1set 0x40000004 +#define asyncLSRDataReady 0x80 +#define asyncLSRFramingError 0x40 +#define asyncLSROverrunError 0x20 +#define asyncLSRParityError 0x10 +#define asyncLSRBreakInterrupt 0x08 +#define asyncLSRTxHoldEmpty 0x04 +#define asyncLSRTxShiftEmpty 0x02 + +/*-----------------------------------------------------------------------------+ + | Handshake Status Register. + +-----------------------------------------------------------------------------*/ +#define asyncHSRport1 0x40000008 +#define asyncHSRport1set 0x4000000c +#define asyncHSRDsr 0x80 +#define asyncLSRCts 0x40 + +/*-----------------------------------------------------------------------------+ + | Control Register. + +-----------------------------------------------------------------------------*/ +#define asyncCRport1 0x40000018 +#define asyncCRNormal 0x00 +#define asyncCRLoopback 0x40 +#define asyncCRAutoEcho 0x80 +#define asyncCRDtr 0x20 +#define asyncCRRts 0x10 +#define asyncCRWordLength7 0x00 +#define asyncCRWordLength8 0x08 +#define asyncCRParityDisable 0x00 +#define asyncCRParityEnable 0x04 +#define asyncCREvenParity 0x00 +#define asyncCROddParity 0x02 +#define asyncCRStopBitsOne 0x00 +#define asyncCRStopBitsTwo 0x01 +#define asyncCRDisableDtrRts 0x00 + +/*-----------------------------------------------------------------------------+ + | Receiver Command Register. + +-----------------------------------------------------------------------------*/ +#define asyncRCRport1 0x4000001c +#define asyncRCRDisable 0x00 +#define asyncRCREnable 0x80 +#define asyncRCRIntDisable 0x00 +#define asyncRCRIntEnabled 0x20 +#define asyncRCRDMACh2 0x40 +#define asyncRCRDMACh3 0x60 +#define asyncRCRErrorInt 0x10 +#define asyncRCRPauseEnable 0x08 + +/*-----------------------------------------------------------------------------+ + | Transmitter Command Register. + +-----------------------------------------------------------------------------*/ +#define asyncTCRport1 0x40000020 +#define asyncTCRDisable 0x00 +#define asyncTCREnable 0x80 +#define asyncTCRIntDisable 0x00 +#define asyncTCRIntEnabled 0x20 +#define asyncTCRDMACh2 0x40 +#define asyncTCRDMACh3 0x60 +#define asyncTCRTxEmpty 0x10 +#define asyncTCRErrorInt 0x08 +#define asyncTCRStopPause 0x04 +#define asyncTCRBreakGen 0x02 + +/*-----------------------------------------------------------------------------+ + | Miscellanies defines. + +-----------------------------------------------------------------------------*/ +#define asyncTxBufferport1 0x40000024 +#define asyncRxBufferport1 0x40000024 +#define asyncDLABLsbport1 0x40000014 +#define asyncDLABMsbport1 0x40000010 +#define asyncXOFFchar 0x13 +#define asyncXONchar 0x11 + + +/* + * Minimal serial functions needed to use one of the SMC ports + * as serial console interface. + */ + +int serial_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + volatile char val; + unsigned short br_reg; + + br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1); + + /* + * Init onboard UART + */ + out8 (SPU_BASE + spu_LineStat_rc, 0x78); /* Clear all bits in Line Status Reg */ + out8 (SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */ + out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */ + out8 (SPU_BASE + spu_CtlReg, 0x08); /* Set 8 bits, no parity and 1 stop bit */ + out8 (SPU_BASE + spu_RxCmd, 0xb0); /* Enable Rx */ + out8 (SPU_BASE + spu_TxCmd, 0x9c); /* Enable Tx */ + out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */ + val = in8 (SPU_BASE + spu_RxBuff); /* Dummy read, to clear receiver */ + + return (0); +} + + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned short br_reg; + + br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1); + + out8 (SPU_BASE + spu_BRateDivl, (br_reg & 0x00ff)); /* Set baud rate divisor... */ + out8 (SPU_BASE + spu_BRateDivh, ((br_reg & 0xff00) >> 8)); /* ... */ +} + + +void serial_putc (const char c) +{ + if (c == '\n') + serial_putc ('\r'); + + /* load status from handshake register */ + if (in8 (SPU_BASE + spu_Handshk_rc) != 00) + out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */ + + out8 (SPU_BASE + spu_TxBuff, c); /* Put char */ + + while ((in8 (SPU_BASE + spu_LineStat_rc) & 04) != 04) { + if (in8 (SPU_BASE + spu_Handshk_rc) != 00) + out8 (SPU_BASE + spu_Handshk_rc, 0xff); /* Clear Handshake */ + } +} + + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + + +int serial_getc () +{ + unsigned char status = 0; + + while (1) { + status = in8 (asyncLSRport1); + if ((status & asyncLSRDataReady) != 0x0) { + break; + } + if ((status & ( asyncLSRFramingError | + asyncLSROverrunError | + asyncLSRParityError | + asyncLSRBreakInterrupt )) != 0) { + (void) out8 (asyncLSRport1, + asyncLSRFramingError | + asyncLSROverrunError | + asyncLSRParityError | + asyncLSRBreakInterrupt ); + } + } + return (0x000000ff & (int) in8 (asyncRxBufferport1)); +} + + +int serial_tstc () +{ + unsigned char status; + + status = in8 (asyncLSRport1); + if ((status & asyncLSRDataReady) != 0x0) { + return (1); + } + if ((status & ( asyncLSRFramingError | + asyncLSROverrunError | + asyncLSRParityError | + asyncLSRBreakInterrupt )) != 0) { + (void) out8 (asyncLSRport1, + asyncLSRFramingError | + asyncLSROverrunError | + asyncLSRParityError | + asyncLSRBreakInterrupt); + } + return 0; +} + +#endif /* CONFIG_IOP480 */ + + +/*****************************************************************************/ +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) + +#if defined(CONFIG_440) +#define UART0_BASE CFG_PERIPHERAL_BASE + 0x00000200 +#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000300 +#define CR0_MASK 0x3fff0000 +#define CR0_EXTCLK_ENA 0x00600000 +#define CR0_UDIV_POS 16 +#else +#define UART_BASE_PTR 0xF800FFFC; /* pointer to uart base */ +#define UART0_BASE 0xef600300 +#define UART1_BASE 0xef600400 +#define CR0_MASK 0x00001fff +#define CR0_EXTCLK_ENA 0x00000c00 +#define CR0_UDIV_POS 1 +#endif + +#define UART_RBR 0x00 +#define UART_THR 0x00 +#define UART_IER 0x01 +#define UART_IIR 0x02 +#define UART_FCR 0x02 +#define UART_LCR 0x03 +#define UART_MCR 0x04 +#define UART_LSR 0x05 +#define UART_MSR 0x06 +#define UART_SCR 0x07 +#define UART_DLL 0x00 +#define UART_DLM 0x01 + +/*-----------------------------------------------------------------------------+ + | Line Status Register. + +-----------------------------------------------------------------------------*/ +/*#define asyncLSRport1 UART0_BASE+0x05 */ +#define asyncLSRDataReady1 0x01 +#define asyncLSROverrunError1 0x02 +#define asyncLSRParityError1 0x04 +#define asyncLSRFramingError1 0x08 +#define asyncLSRBreakInterrupt1 0x10 +#define asyncLSRTxHoldEmpty1 0x20 +#define asyncLSRTxShiftEmpty1 0x40 +#define asyncLSRRxFifoError1 0x80 + +/*-----------------------------------------------------------------------------+ + | Miscellanies defines. + +-----------------------------------------------------------------------------*/ +/*#define asyncTxBufferport1 UART0_BASE+0x00 */ +/*#define asyncRxBufferport1 UART0_BASE+0x00 */ + + +#if CONFIG_SERIAL_SOFTWARE_FIFO +/*-----------------------------------------------------------------------------+ + | Fifo + +-----------------------------------------------------------------------------*/ +typedef struct { + char *rx_buffer; + ulong rx_put; + ulong rx_get; +} serial_buffer_t; + +volatile static serial_buffer_t buf_info; +#endif + + +#if defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLOCK) +static void serial_divs (int baudrate, unsigned long *pudiv, + unsigned short *pbdiv ) +{ + sys_info_t sysinfo; + unsigned long div; /* total divisor udiv * bdiv */ + unsigned long umin; /* minimum udiv */ + unsigned short diff; /* smallest diff */ + unsigned long udiv; /* best udiv */ + + unsigned short idiff; /* current diff */ + unsigned short ibdiv; /* current bdiv */ + unsigned long i; + unsigned long est; /* current estimate */ + + get_sys_info( &sysinfo ); + + udiv = 32; /* Assume lowest possible serial clk */ + div = sysinfo.freqPLB/(16*baudrate); /* total divisor */ + umin = sysinfo.pllOpbDiv<<1; /* 2 x OPB divisor */ + diff = 32; /* highest possible */ + + /* i is the test udiv value -- start with the largest + * possible (32) to minimize serial clock and constrain + * search to umin. + */ + for( i = 32; i > umin; i-- ){ + ibdiv = div/i; + est = i * ibdiv; + idiff = (est > div) ? (est-div) : (div-est); + if( idiff == 0 ){ + udiv = i; + break; /* can't do better */ + } + else if( idiff < diff ){ + udiv = i; /* best so far */ + diff = idiff; /* update lowest diff*/ + } + } + + *pudiv = udiv; + *pbdiv = div/udiv; + +} +#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */ + + +/* + * Minimal serial functions needed to use one of the SMC ports + * as serial console interface. + */ + +#if defined(CONFIG_440) +int serial_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned long reg; + unsigned long udiv; + unsigned short bdiv; + volatile char val; +#ifdef CFG_EXT_SERIAL_CLOCK + unsigned long tmp; +#endif + + reg = mfdcr(cntrl0) & ~CR0_MASK; +#ifdef CFG_EXT_SERIAL_CLOCK + reg |= CR0_EXTCLK_ENA; + udiv = 1; + tmp = gd->baudrate * 16; + bdiv = (CFG_EXT_SERIAL_CLOCK + tmp / 2) / tmp; +#else + /* For 440, the cpu clock is on divider chain A, UART on divider + * chain B ... so cpu clock is irrelevant. Get the "optimized" + * values that are subject to the 1/2 opb clock constraint + */ + serial_divs (gd->baudrate, &udiv, &bdiv); +#endif + + reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */ + mtdcr (cntrl0, reg); + + out8 (UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */ + out8 (UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */ + out8 (UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */ + out8 (UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */ + out8 (UART0_BASE + UART_FCR, 0x00); /* disable FIFO */ + out8 (UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */ + val = in8 (UART0_BASE + UART_LSR); /* clear line status */ + val = in8 (UART0_BASE + UART_RBR); /* read receive buffer */ + out8 (UART0_BASE + UART_SCR, 0x00); /* set scratchpad */ + out8 (UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */ + + return (0); +} + +#else /* !defined(CONFIG_440) */ + +int serial_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned long reg; + unsigned long tmp; + unsigned long clk; + unsigned long udiv; + unsigned short bdiv; + volatile char val; + + reg = mfdcr(cntrl0) & ~CR0_MASK; +#ifdef CFG_EXT_SERIAL_CLOCK + clk = CFG_EXT_SERIAL_CLOCK; + udiv = 1; + reg |= CR0_EXTCLK_ENA; +#else + clk = gd->cpu_clk; +#ifdef CFG_405_UART_ERRATA_59 + udiv = 31; /* Errata 59: stuck at 31 */ +#else + tmp = CFG_BASE_BAUD * 16; + udiv = (clk + tmp / 2) / tmp; +#endif +#endif + + reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */ + mtdcr (cntrl0, reg); + + tmp = gd->baudrate * udiv * 16; + bdiv = (clk + tmp / 2) / tmp; + + out8 (UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */ + out8 (UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */ + out8 (UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */ + out8 (UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */ + out8 (UART0_BASE + UART_FCR, 0x00); /* disable FIFO */ + out8 (UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */ + val = in8 (UART0_BASE + UART_LSR); /* clear line status */ + val = in8 (UART0_BASE + UART_RBR); /* read receive buffer */ + out8 (UART0_BASE + UART_SCR, 0x00); /* set scratchpad */ + out8 (UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */ + + return (0); +} + +#endif /* if defined(CONFIG_440) */ + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned long tmp; + unsigned long clk; + unsigned long udiv; + unsigned short bdiv; + +#ifdef CFG_EXT_SERIAL_CLOCK + clk = CFG_EXT_SERIAL_CLOCK; +#else + clk = gd->cpu_clk; +#endif + udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1; + tmp = gd->baudrate * udiv * 16; + bdiv = (clk + tmp / 2) / tmp; + + out8 (UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */ + out8 (UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */ + out8 (UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */ + out8 (UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */ +} + + +void serial_putc (const char c) +{ + int i; + + if (c == '\n') + serial_putc ('\r'); + + /* check THRE bit, wait for transmiter available */ + for (i = 1; i < 3500; i++) { + if ((in8 (UART0_BASE + UART_LSR) & 0x20) == 0x20) + break; + udelay (100); + } + out8 (UART0_BASE + UART_THR, c); /* put character out */ +} + + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + + +int serial_getc () +{ + unsigned char status = 0; + + while (1) { +#if defined(CONFIG_HW_WATCHDOG) + WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ +#endif /* CONFIG_HW_WATCHDOG */ + status = in8 (UART0_BASE + UART_LSR); + if ((status & asyncLSRDataReady1) != 0x0) { + break; + } + if ((status & ( asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1 )) != 0) { + out8 (UART0_BASE + UART_LSR, + asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1); + } + } + return (0x000000ff & (int) in8 (UART0_BASE)); +} + + +int serial_tstc () +{ + unsigned char status; + + status = in8 (UART0_BASE + UART_LSR); + if ((status & asyncLSRDataReady1) != 0x0) { + return (1); + } + if ((status & ( asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1 )) != 0) { + out8 (UART0_BASE + UART_LSR, + asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1); + } + return 0; +} + + +#if CONFIG_SERIAL_SOFTWARE_FIFO + +void serial_isr (void *arg) +{ + int space; + int c; + const int rx_get = buf_info.rx_get; + int rx_put = buf_info.rx_put; + + if (rx_get <= rx_put) { + space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get); + } else { + space = rx_get - rx_put; + } + while (serial_tstc ()) { + c = serial_getc (); + if (space) { + buf_info.rx_buffer[rx_put++] = c; + space--; + } + if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) + rx_put = 0; + if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) { + /* Stop flow by setting RTS inactive */ + out8 (UART0_BASE + UART_MCR, + in8 (UART0_BASE + UART_MCR) & (0xFF ^ 0x02)); + } + } + buf_info.rx_put = rx_put; +} + +void serial_buffered_init (void) +{ + serial_puts ("Switching to interrupt driven serial input mode.\n"); + buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO); + buf_info.rx_put = 0; + buf_info.rx_get = 0; + + if (in8 (UART0_BASE + UART_MSR) & 0x10) { + serial_puts ("Check CTS signal present on serial port: OK.\n"); + } else { + serial_puts ("WARNING: CTS signal not present on serial port.\n"); + } + + irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ , + serial_isr /*interrupt_handler_t *handler */ , + (void *) &buf_info /*void *arg */ ); + + /* Enable "RX Data Available" Interrupt on UART */ + /* out8(UART0_BASE + UART_IER, in8(UART0_BASE + UART_IER) |0x01); */ + out8 (UART0_BASE + UART_IER, 0x01); + /* Set DTR active */ + out8 (UART0_BASE + UART_MCR, in8 (UART0_BASE + UART_MCR) | 0x01); + /* Start flow by setting RTS active */ + out8 (UART0_BASE + UART_MCR, in8 (UART0_BASE + UART_MCR) | 0x02); + /* Setup UART FIFO: RX trigger level: 4 byte, Enable FIFO */ + out8 (UART0_BASE + UART_FCR, (1 << 6) | 1); +} + +void serial_buffered_putc (const char c) +{ + /* Wait for CTS */ +#if defined(CONFIG_HW_WATCHDOG) + while (!(in8 (UART0_BASE + UART_MSR) & 0x10)) + WATCHDOG_RESET (); +#else + while (!(in8 (UART0_BASE + UART_MSR) & 0x10)); +#endif + serial_putc (c); +} + +void serial_buffered_puts (const char *s) +{ + serial_puts (s); +} + +int serial_buffered_getc (void) +{ + int space; + int c; + int rx_get = buf_info.rx_get; + int rx_put; + +#if defined(CONFIG_HW_WATCHDOG) + while (rx_get == buf_info.rx_put) + WATCHDOG_RESET (); +#else + while (rx_get == buf_info.rx_put); +#endif + c = buf_info.rx_buffer[rx_get++]; + if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO) + rx_get = 0; + buf_info.rx_get = rx_get; + + rx_put = buf_info.rx_put; + if (rx_get <= rx_put) { + space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get); + } else { + space = rx_get - rx_put; + } + if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) { + /* Start flow by setting RTS active */ + out8 (UART0_BASE + UART_MCR, in8 (UART0_BASE + UART_MCR) | 0x02); + } + + return c; +} + +int serial_buffered_tstc (void) +{ + return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0; +} + +#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */ + + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +/* + AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port + number 0 or number 1 + - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 : + configuration has been already done + - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 : + configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE +*/ +#if (CONFIG_KGDB_SER_INDEX & 2) +void kgdb_serial_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + volatile char val; + unsigned short br_reg; + + get_clocks (); + br_reg = (((((gd->cpu_clk / 16) / 18) * 10) / CONFIG_KGDB_BAUDRATE) + + 5) / 10; + /* + * Init onboard 16550 UART + */ + out8 (UART1_BASE + UART_LCR, 0x80); /* set DLAB bit */ + out8 (UART1_BASE + UART_DLL, (br_reg & 0x00ff)); /* set divisor for 9600 baud */ + out8 (UART1_BASE + UART_DLM, ((br_reg & 0xff00) >> 8)); /* set divisor for 9600 baud */ + out8 (UART1_BASE + UART_LCR, 0x03); /* line control 8 bits no parity */ + out8 (UART1_BASE + UART_FCR, 0x00); /* disable FIFO */ + out8 (UART1_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */ + val = in8 (UART1_BASE + UART_LSR); /* clear line status */ + val = in8 (UART1_BASE + UART_RBR); /* read receive buffer */ + out8 (UART1_BASE + UART_SCR, 0x00); /* set scratchpad */ + out8 (UART1_BASE + UART_IER, 0x00); /* set interrupt enable reg */ +} + + +void putDebugChar (const char c) +{ + if (c == '\n') + serial_putc ('\r'); + + out8 (UART1_BASE + UART_THR, c); /* put character out */ + + /* check THRE bit, wait for transfer done */ + while ((in8 (UART1_BASE + UART_LSR) & 0x20) != 0x20); +} + + +void putDebugStr (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + + +int getDebugChar (void) +{ + unsigned char status = 0; + + while (1) { + status = in8 (UART1_BASE + UART_LSR); + if ((status & asyncLSRDataReady1) != 0x0) { + break; + } + if ((status & ( asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1 )) != 0) { + out8 (UART1_BASE + UART_LSR, + asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1); + } + } + return (0x000000ff & (int) in8 (UART1_BASE)); +} + + +void kgdb_interruptible (int yes) +{ + return; +} + +#else /* ! (CONFIG_KGDB_SER_INDEX & 2) */ + +void kgdb_serial_init (void) +{ + serial_printf ("[on serial] "); +} + +void putDebugChar (int c) +{ + serial_putc (c); +} + +void putDebugStr (const char *str) +{ + serial_puts (str); +} + +int getDebugChar (void) +{ + return serial_getc (); +} + +void kgdb_interruptible (int yes) +{ + return; +} +#endif /* (CONFIG_KGDB_SER_INDEX & 2) */ +#endif /* CFG_CMD_KGDB */ + +#endif /* CONFIG_405GP || CONFIG_405CR */ diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c new file mode 100644 index 0000000..fc0c980 --- /dev/null +++ b/cpu/ppc4xx/spd_sdram.c @@ -0,0 +1,1764 @@ +/* + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com + * + * Based on code by: + * + * Kenneth Johansson ,Ericsson Business Innovation. + * kenneth.johansson@inn.ericsson.se + * + * hacked up by bill hunter. fixed so we could run before + * serial_init and console_init. previous version avoided this by + * running out of cache memory during serial/console init, then running + * this code later. + * + * (C) Copyright 2002 + * Jun Gu, Artesyn Technology, jung@artesyncp.com + * Support for IBM 440 based on OpenBIOS draminit.c from IBM. + * + * 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 <common.h> +#include <asm/processor.h> +#include <i2c.h> +#include <ppc4xx.h> + +#ifdef CONFIG_SPD_EEPROM + +/* + * Set default values + */ +#ifndef CFG_I2C_SPEED +#define CFG_I2C_SPEED 50000 +#endif + +#ifndef CFG_I2C_SLAVE +#define CFG_I2C_SLAVE 0xFE +#endif + +#ifndef CONFIG_440 /* for 405 WALNUT board */ + +#define SDRAM0_CFG_DCE 0x80000000 +#define SDRAM0_CFG_SRE 0x40000000 +#define SDRAM0_CFG_PME 0x20000000 +#define SDRAM0_CFG_MEMCHK 0x10000000 +#define SDRAM0_CFG_REGEN 0x08000000 +#define SDRAM0_CFG_ECCDD 0x00400000 +#define SDRAM0_CFG_EMDULR 0x00200000 +#define SDRAM0_CFG_DRW_SHIFT (31-6) +#define SDRAM0_CFG_BRPF_SHIFT (31-8) + +#define SDRAM0_TR_CASL_SHIFT (31-8) +#define SDRAM0_TR_PTA_SHIFT (31-13) +#define SDRAM0_TR_CTP_SHIFT (31-15) +#define SDRAM0_TR_LDF_SHIFT (31-17) +#define SDRAM0_TR_RFTA_SHIFT (31-29) +#define SDRAM0_TR_RCD_SHIFT (31-31) + +#define SDRAM0_RTR_SHIFT (31-15) +#define SDRAM0_ECCCFG_SHIFT (31-11) + +/* SDRAM0_CFG enable macro */ +#define SDRAM0_CFG_BRPF(x) ( ( x & 0x3)<< SDRAM0_CFG_BRPF_SHIFT ) + +#define SDRAM0_BXCR_SZ_MASK 0x000e0000 +#define SDRAM0_BXCR_AM_MASK 0x0000e000 + +#define SDRAM0_BXCR_SZ_SHIFT (31-14) +#define SDRAM0_BXCR_AM_SHIFT (31-18) + +#define SDRAM0_BXCR_SZ(x) ( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) ) +#define SDRAM0_BXCR_AM(x) ( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) ) + +#ifdef CONFIG_W7O +# define SPD_ERR(x) do { return 0; } while (0) +#else +# define SPD_ERR(x) do { printf(x); hang(); } while (0) +#endif + +/* + * what we really want is + * (1/hertz) but we don't want to use floats so multiply with 10E9 + * + * The error needs to be on the safe side so we want the floor function. + * This means we get an exact value or we calculate that our bus frequency is + * a bit faster than it really is and thus we don't progam the sdram controller + * to run to fast + */ +#define sdram_HZ_to_ns(hertz) (1000000000/(hertz)) + +/* function prototypes */ +int spd_read(uint addr); /* prototype */ + + +/* + * This function is reading data from the DIMM module EEPROM over the SPD bus + * and uses that to program the sdram controller. + * + * This works on boards that has the same schematics that the IBM walnut has. + * + * BUG: Don't handle ECC memory + * BUG: A few values in the TR register is currently hardcoded + */ + +long int spd_sdram(void) +{ + int bus_period,tmp,row,col; + int total_size,bank_size,bank_code; + int ecc_on; + int mode = 4; + int bank_cnt = 1; + + int sdram0_pmit=0x07c00000; + int sdram0_besr0=-1; + int sdram0_besr1=-1; + int sdram0_eccesr=-1; + int sdram0_ecccfg; + + int sdram0_rtr=0; + int sdram0_tr=0; + + int sdram0_b0cr; + int sdram0_b1cr; + int sdram0_b2cr; + int sdram0_b3cr; + + int sdram0_cfg=0; + + int t_rp; + int t_rcd; + int t_rc = 70; /* This value not available in SPD_EEPROM */ + int min_cas = 2; + + /* + * Make sure I2C controller is initialized + * before continuing. + */ + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + + /* + * Calculate the bus period, we do it this + * way to minimize stack utilization. + */ + tmp = (mfdcr(pllmd) >> (31-6)) & 0xf; /* get FBDV bits */ + tmp = CONFIG_SYS_CLK_FREQ * tmp; /* get plb freq */ + bus_period = sdram_HZ_to_ns(tmp); /* get sdram speed */ + + /* Make shure we are using SDRAM */ + if (spd_read(2) != 0x04){ + SPD_ERR("SDRAM - non SDRAM memory module found\n"); + } + +/*------------------------------------------------------------------ + configure memory timing register + + data from DIMM: + 27 IN Row Precharge Time ( t RP) + 29 MIN RAS to CAS Delay ( t RCD) + 127 Component and Clock Detail ,clk0-clk3, junction temp, CAS + -------------------------------------------------------------------*/ + + /* + * first figure out which cas latency mode to use + * use the min supported mode + */ + + tmp = spd_read(127) & 0x6; + if(tmp == 0x02){ /* only cas = 2 supported */ + min_cas = 2; +/* t_ck = spd_read(9); */ +/* t_ac = spd_read(10); */ + } + else if (tmp == 0x04){ /* only cas = 3 supported */ + min_cas = 3; +/* t_ck = spd_read(9); */ +/* t_ac = spd_read(10); */ + } + else if (tmp == 0x06){ /* 2,3 supported, so use 2 */ + min_cas = 2; +/* t_ck = spd_read(23); */ +/* t_ac = spd_read(24); */ + } + else { + SPD_ERR("SDRAM - unsupported CAS latency \n"); + } + + /* get some timing values, t_rp,t_rcd + */ + t_rp = spd_read(27); + t_rcd = spd_read(29); + + + /* The following timing calcs subtract 1 before deviding. + * this has effect of using ceiling intead of floor rounding, + * and also subtracting 1 to convert number to reg value + */ + /* set up CASL */ + sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT; + /* set up PTA */ + sdram0_tr |= (((t_rp - 1)/bus_period) & 0x3) << SDRAM0_TR_PTA_SHIFT; + /* set up CTP */ + tmp = ((t_rc - t_rcd - t_rp -1) / bus_period) & 0x3; + if(tmp<1) SPD_ERR("SDRAM - unsupported prech to act time (Trp)\n"); + sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT; + /* set LDF = 2 cycles, reg value = 1 */ + sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT; + /* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */ + tmp = ((t_rc - 1) / bus_period)-4; + if(tmp<0)tmp=0; + if(tmp>6)tmp=6; + sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT; + /* set RCD = t_rcd/bus_period*/ + sdram0_tr |= (((t_rcd - 1) / bus_period) &0x3) << SDRAM0_TR_RCD_SHIFT ; + + +/*------------------------------------------------------------------ + configure RTR register + -------------------------------------------------------------------*/ + row = spd_read(3); + col = spd_read(4); + tmp = spd_read(12) & 0x7f ; /* refresh type less self refresh bit */ + switch(tmp){ + case 0x00: + tmp=15625; + break; + case 0x01: + tmp=15625/4; + break; + case 0x02: + tmp=15625/2; + break; + case 0x03: + tmp=15625*2; + break; + case 0x04: + tmp=15625*4; + break; + case 0x05: + tmp=15625*8; + break; + default: + SPD_ERR("SDRAM - Bad refresh period \n"); + } + /* convert from nsec to bus cycles */ + tmp = tmp/bus_period; + sdram0_rtr = (tmp & 0x3ff8)<< SDRAM0_RTR_SHIFT; + +/*------------------------------------------------------------------ + determine the number of banks used + -------------------------------------------------------------------*/ + /* byte 7:6 is module data width */ + if(spd_read(7) != 0) + SPD_ERR("SDRAM - unsupported module width\n"); + tmp = spd_read(6); + if (tmp < 32) + SPD_ERR("SDRAM - unsupported module width\n"); + else if (tmp < 64) + bank_cnt=1; /* one bank per sdram side */ + else if (tmp < 73) + bank_cnt=2; /* need two banks per side */ + else if (tmp < 161) + bank_cnt=4; /* need four banks per side */ + else + SPD_ERR("SDRAM - unsupported module width\n"); + + /* byte 5 is the module row count (refered to as dimm "sides") */ + tmp = spd_read(5); + if(tmp==1); + else if(tmp==2) bank_cnt *=2; + else if(tmp==4) bank_cnt *=4; + else bank_cnt = 8; /* 8 is an error code */ + + if(bank_cnt > 4) /* we only have 4 banks to work with */ + SPD_ERR("SDRAM - unsupported module rows for this width\n"); + + /* now check for ECC ability of module. We only support ECC + * on 32 bit wide devices with 8 bit ECC. + */ + if ( (spd_read(11)==2) && ((spd_read(6)==40) || (spd_read(14)==8)) ){ + sdram0_ecccfg=0xf<<SDRAM0_ECCCFG_SHIFT; + ecc_on = 1; + } + else{ + sdram0_ecccfg=0; + ecc_on = 0; + } + +/*------------------------------------------------------------------ + calculate total size + -------------------------------------------------------------------*/ + /* calculate total size and do sanity check */ + tmp = spd_read(31); + total_size=1<<22; /* total_size = 4MB */ + /* now multiply 4M by the smallest device roe density */ + /* note that we don't support asymetric rows */ + while (((tmp & 0x0001) == 0) && (tmp != 0)){ + total_size= total_size<<1; + tmp = tmp>>1; + } + total_size *= spd_read(5); /* mult by module rows (dimm sides) */ + +/*------------------------------------------------------------------ + map rows * cols * banks to a mode + -------------------------------------------------------------------*/ + + switch( row ) + { + case 11: + switch ( col ) + { + case 8: + mode=4; /* mode 5 */ + break; + case 9: + case 10: + mode=0; /* mode 1 */ + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + break; + case 12: + switch ( col ) + { + case 8: + mode=3; /* mode 4 */ + break; + case 9: + case 10: + mode=1; /* mode 2 */ + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + break; + case 13: + switch ( col ) + { + case 8: + mode=5; /* mode 6 */ + break; + case 9: + case 10: + if (spd_read(17) ==2 ) + mode=6; /* mode 7 */ + else + mode=2; /* mode 3 */ + break; + case 11: + mode=2; /* mode 3 */ + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + +/*------------------------------------------------------------------ + using the calculated values, compute the bank + config register values. + -------------------------------------------------------------------*/ + sdram0_b1cr = 0; + sdram0_b2cr = 0; + sdram0_b3cr = 0; + + /* compute the size of each bank */ + bank_size = total_size / bank_cnt; + /* convert bank size to bank size code for ppc4xx + by takeing log2(bank_size) - 22 */ + tmp=bank_size; /* start with tmp = bank_size */ + bank_code=0; /* and bank_code = 0 */ + while (tmp>1){ /* this takes log2 of tmp */ + bank_code++; /* and stores result in bank_code */ + tmp=tmp>>1; + } /* bank_code is now log2(bank_size) */ + bank_code-=22; /* subtract 22 to get the code */ + + tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1; + sdram0_b0cr = (bank_size) * 0 | tmp; + if(bank_cnt>1) sdram0_b2cr = (bank_size) * 1 | tmp; + if(bank_cnt>2) sdram0_b1cr = (bank_size) * 2 | tmp; + if(bank_cnt>3) sdram0_b3cr = (bank_size) * 3 | tmp; + + + /* + * enable sdram controller DCE=1 + * enable burst read prefetch to 32 bytes BRPF=2 + * leave other functions off + */ + +/*------------------------------------------------------------------ + now that we've done our calculations, we are ready to + program all the registers. + -------------------------------------------------------------------*/ + + +#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) + /* disable memcontroller so updates work */ + sdram0_cfg = 0; + mtsdram0( mem_mcopt1, sdram0_cfg ); + + mtsdram0( mem_besra , sdram0_besr0 ); + mtsdram0( mem_besrb , sdram0_besr1 ); + mtsdram0( mem_rtr , sdram0_rtr ); + mtsdram0( mem_pmit , sdram0_pmit ); + mtsdram0( mem_mb0cf , sdram0_b0cr ); + mtsdram0( mem_mb1cf , sdram0_b1cr ); + mtsdram0( mem_mb2cf , sdram0_b2cr ); + mtsdram0( mem_mb3cf , sdram0_b3cr ); + mtsdram0( mem_sdtr1 , sdram0_tr ); + mtsdram0( mem_ecccf , sdram0_ecccfg ); + mtsdram0( mem_eccerr, sdram0_eccesr ); + + /* SDRAM have a power on delay, 500 micro should do */ + udelay(500); + sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR; + if(ecc_on) sdram0_cfg |= SDRAM0_CFG_MEMCHK; + mtsdram0( mem_mcopt1, sdram0_cfg ); + + + /* kernel 2.4.2 from mvista has a bug with memory over 128MB */ +#ifdef MVISTA_MEM_BUG + if (total_size > 128*1024*1024 ) + total_size=128*1024*1024; +#endif + return (total_size); +} + +int spd_read(uint addr) +{ + char data[2]; + + if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0) + return (int)data[0]; + else + return 0; +} + +#else /* CONFIG_440 */ + +/*----------------------------------------------------------------------------- +| Memory Controller Options 0 ++-----------------------------------------------------------------------------*/ +#define SDRAM_CFG0_DCEN 0x80000000 /* SDRAM Controller Enable */ +#define SDRAM_CFG0_MCHK_MASK 0x30000000 /* Memory data errchecking mask */ +#define SDRAM_CFG0_MCHK_NON 0x00000000 /* No ECC generation */ +#define SDRAM_CFG0_MCHK_GEN 0x20000000 /* ECC generation */ +#define SDRAM_CFG0_MCHK_CHK 0x30000000 /* ECC generation and checking */ +#define SDRAM_CFG0_RDEN 0x08000000 /* Registered DIMM enable */ +#define SDRAM_CFG0_PMUD 0x04000000 /* Page management unit */ +#define SDRAM_CFG0_DMWD_MASK 0x02000000 /* DRAM width mask */ +#define SDRAM_CFG0_DMWD_32 0x00000000 /* 32 bits */ +#define SDRAM_CFG0_DMWD_64 0x02000000 /* 64 bits */ +#define SDRAM_CFG0_UIOS_MASK 0x00C00000 /* Unused IO State */ +#define SDRAM_CFG0_PDP 0x00200000 /* Page deallocation policy */ + +/*----------------------------------------------------------------------------- +| Memory Controller Options 1 ++-----------------------------------------------------------------------------*/ +#define SDRAM_CFG1_SRE 0x80000000 /* Self-Refresh Entry */ +#define SDRAM_CFG1_PMEN 0x40000000 /* Power Management Enable */ + +/*-----------------------------------------------------------------------------+ +| SDRAM DEVPOT Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_DEVOPT_DLL 0x80000000 +#define SDRAM_DEVOPT_DS 0x40000000 + +/*-----------------------------------------------------------------------------+ +| SDRAM MCSTS Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_MCSTS_MRSC 0x80000000 +#define SDRAM_MCSTS_SRMS 0x40000000 +#define SDRAM_MCSTS_CIS 0x20000000 + +/*----------------------------------------------------------------------------- +| SDRAM Refresh Timer Register ++-----------------------------------------------------------------------------*/ +#define SDRAM_RTR_RINT_MASK 0xFFFF0000 +#define SDRAM_RTR_RINT_ENCODE(n) (((n) << 16) & SDRAM_RTR_RINT_MASK) +#define sdram_HZ_to_ns(hertz) (1000000000/(hertz)) + +/*-----------------------------------------------------------------------------+ +| SDRAM UABus Base Address Reg ++-----------------------------------------------------------------------------*/ +#define SDRAM_UABBA_UBBA_MASK 0x0000000F + +/*-----------------------------------------------------------------------------+ +| Memory Bank 0-7 configuration ++-----------------------------------------------------------------------------*/ +#define SDRAM_BXCR_SDBA_MASK 0xff800000 /* Base address */ +#define SDRAM_BXCR_SDSZ_MASK 0x000e0000 /* Size */ +#define SDRAM_BXCR_SDSZ_8 0x00020000 /* 8M */ +#define SDRAM_BXCR_SDSZ_16 0x00040000 /* 16M */ +#define SDRAM_BXCR_SDSZ_32 0x00060000 /* 32M */ +#define SDRAM_BXCR_SDSZ_64 0x00080000 /* 64M */ +#define SDRAM_BXCR_SDSZ_128 0x000a0000 /* 128M */ +#define SDRAM_BXCR_SDSZ_256 0x000c0000 /* 256M */ +#define SDRAM_BXCR_SDSZ_512 0x000e0000 /* 512M */ +#define SDRAM_BXCR_SDAM_MASK 0x0000e000 /* Addressing mode */ +#define SDRAM_BXCR_SDAM_1 0x00000000 /* Mode 1 */ +#define SDRAM_BXCR_SDAM_2 0x00002000 /* Mode 2 */ +#define SDRAM_BXCR_SDAM_3 0x00004000 /* Mode 3 */ +#define SDRAM_BXCR_SDAM_4 0x00006000 /* Mode 4 */ +#define SDRAM_BXCR_SDBE 0x00000001 /* Memory Bank Enable */ + +/*-----------------------------------------------------------------------------+ +| SDRAM TR0 Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_TR0_SDWR_MASK 0x80000000 +#define SDRAM_TR0_SDWR_2_CLK 0x00000000 +#define SDRAM_TR0_SDWR_3_CLK 0x80000000 +#define SDRAM_TR0_SDWD_MASK 0x40000000 +#define SDRAM_TR0_SDWD_0_CLK 0x00000000 +#define SDRAM_TR0_SDWD_1_CLK 0x40000000 +#define SDRAM_TR0_SDCL_MASK 0x01800000 +#define SDRAM_TR0_SDCL_2_0_CLK 0x00800000 +#define SDRAM_TR0_SDCL_2_5_CLK 0x01000000 +#define SDRAM_TR0_SDCL_3_0_CLK 0x01800000 +#define SDRAM_TR0_SDPA_MASK 0x000C0000 +#define SDRAM_TR0_SDPA_2_CLK 0x00040000 +#define SDRAM_TR0_SDPA_3_CLK 0x00080000 +#define SDRAM_TR0_SDPA_4_CLK 0x000C0000 +#define SDRAM_TR0_SDCP_MASK 0x00030000 +#define SDRAM_TR0_SDCP_2_CLK 0x00000000 +#define SDRAM_TR0_SDCP_3_CLK 0x00010000 +#define SDRAM_TR0_SDCP_4_CLK 0x00020000 +#define SDRAM_TR0_SDCP_5_CLK 0x00030000 +#define SDRAM_TR0_SDLD_MASK 0x0000C000 +#define SDRAM_TR0_SDLD_1_CLK 0x00000000 +#define SDRAM_TR0_SDLD_2_CLK 0x00004000 +#define SDRAM_TR0_SDRA_MASK 0x0000001C +#define SDRAM_TR0_SDRA_6_CLK 0x00000000 +#define SDRAM_TR0_SDRA_7_CLK 0x00000004 +#define SDRAM_TR0_SDRA_8_CLK 0x00000008 +#define SDRAM_TR0_SDRA_9_CLK 0x0000000C +#define SDRAM_TR0_SDRA_10_CLK 0x00000010 +#define SDRAM_TR0_SDRA_11_CLK 0x00000014 +#define SDRAM_TR0_SDRA_12_CLK 0x00000018 +#define SDRAM_TR0_SDRA_13_CLK 0x0000001C +#define SDRAM_TR0_SDRD_MASK 0x00000003 +#define SDRAM_TR0_SDRD_2_CLK 0x00000001 +#define SDRAM_TR0_SDRD_3_CLK 0x00000002 +#define SDRAM_TR0_SDRD_4_CLK 0x00000003 + +/*-----------------------------------------------------------------------------+ +| SDRAM TR1 Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_TR1_RDSS_MASK 0xC0000000 +#define SDRAM_TR1_RDSS_TR0 0x00000000 +#define SDRAM_TR1_RDSS_TR1 0x40000000 +#define SDRAM_TR1_RDSS_TR2 0x80000000 +#define SDRAM_TR1_RDSS_TR3 0xC0000000 +#define SDRAM_TR1_RDSL_MASK 0x00C00000 +#define SDRAM_TR1_RDSL_STAGE1 0x00000000 +#define SDRAM_TR1_RDSL_STAGE2 0x00400000 +#define SDRAM_TR1_RDSL_STAGE3 0x00800000 +#define SDRAM_TR1_RDCD_MASK 0x00000800 +#define SDRAM_TR1_RDCD_RCD_0_0 0x00000000 +#define SDRAM_TR1_RDCD_RCD_1_2 0x00000800 +#define SDRAM_TR1_RDCT_MASK 0x000001FF +#define SDRAM_TR1_RDCT_ENCODE(x) (((x) << 0) & SDRAM_TR1_RDCT_MASK) +#define SDRAM_TR1_RDCT_DECODE(x) (((x) & SDRAM_TR1_RDCT_MASK) >> 0) +#define SDRAM_TR1_RDCT_MIN 0x00000000 +#define SDRAM_TR1_RDCT_MAX 0x000001FF + +/*-----------------------------------------------------------------------------+ +| SDRAM WDDCTR Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_WDDCTR_WRCP_MASK 0xC0000000 +#define SDRAM_WDDCTR_WRCP_0DEG 0x00000000 +#define SDRAM_WDDCTR_WRCP_90DEG 0x40000000 +#define SDRAM_WDDCTR_WRCP_180DEG 0x80000000 +#define SDRAM_WDDCTR_DCD_MASK 0x000001FF + +/*-----------------------------------------------------------------------------+ +| SDRAM CLKTR Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_CLKTR_CLKP_MASK 0xC0000000 +#define SDRAM_CLKTR_CLKP_0DEG 0x00000000 +#define SDRAM_CLKTR_CLKP_90DEG 0x40000000 +#define SDRAM_CLKTR_CLKP_180DEG 0x80000000 +#define SDRAM_CLKTR_DCDT_MASK 0x000001FF + +/*-----------------------------------------------------------------------------+ +| SDRAM DLYCAL Options ++-----------------------------------------------------------------------------*/ +#define SDRAM_DLYCAL_DLCV_MASK 0x000003FC +#define SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK) +#define SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2) + +/*-----------------------------------------------------------------------------+ +| General Definition ++-----------------------------------------------------------------------------*/ +#define DEFAULT_SPD_ADDR1 0x53 +#define DEFAULT_SPD_ADDR2 0x52 +#define ONE_BILLION 1000000000 +#define MAXBANKS 4 /* at most 4 dimm banks */ +#define MAX_SPD_BYTES 256 +#define NUMHALFCYCLES 4 +#define NUMMEMTESTS 8 +#define NUMMEMWORDS 8 +#define MAXBXCR 4 +#define TRUE 1 +#define FALSE 0 + +const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { + {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000}, + {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555}, + {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA}, + {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, + 0x5A5A5A5A, 0x5A5A5A5A}, + {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, + 0xA5A5A5A5, 0xA5A5A5A5}, + {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, + 0x55AA55AA, 0x55AA55AA}, + {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, + 0xAA55AA55, 0xAA55AA55} +}; + + +unsigned char spd_read(uchar chip, uint addr); + +void get_spd_info(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void check_mem_type + (unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void check_volt_type + (unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void program_cfg0(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void program_cfg1(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void program_rtr (unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void program_tr0 (unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +void program_tr1 (void); + +void program_ecc (unsigned long num_bytes); + +unsigned +long program_bxcr(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks); + +/* + * This function is reading data from the DIMM module EEPROM over the SPD bus + * and uses that to program the sdram controller. + * + * This works on boards that has the same schematics that the IBM walnut has. + * + * BUG: Don't handle ECC memory + * BUG: A few values in the TR register is currently hardcoded + */ + +long int spd_sdram(void) { + unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS; + unsigned long dimm_populated[sizeof(iic0_dimm_addr)]; + unsigned long total_size; + unsigned long cfg0; + unsigned long mcsts; + unsigned long num_dimm_banks; /* on board dimm banks */ + + num_dimm_banks = sizeof(iic0_dimm_addr); + + /* + * Make sure I2C controller is initialized + * before continuing. + */ + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + + /* + * Read the SPD information using I2C interface. Check to see if the + * DIMM slots are populated. + */ + get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * Check the memory type for the dimms plugged. + */ + check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * Check the voltage type for the dimms plugged. + */ + check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * program 440GP SDRAM controller options (SDRAM0_CFG0) + */ + program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * program 440GP SDRAM controller options (SDRAM0_CFG1) + */ + program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * program SDRAM refresh register (SDRAM0_RTR) + */ + program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * program SDRAM Timing Register 0 (SDRAM0_TR0) + */ + program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /* + * program the BxCR registers to find out total sdram installed + */ + total_size = program_bxcr(dimm_populated, iic0_dimm_addr, + num_dimm_banks); + + /* + * program SDRAM Clock Timing Register (SDRAM0_CLKTR) + */ + mtsdram(mem_clktr, 0x40000000); + + /* + * delay to ensure 200 usec has elapsed + */ + udelay(400); + + /* + * enable the memory controller + */ + mfsdram(mem_cfg0, cfg0); + mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN); + + /* + * wait for SDRAM_CFG0_DC_EN to complete + */ + while(1) { + mfsdram(mem_mcsts, mcsts); + if ((mcsts & SDRAM_MCSTS_MRSC) != 0) { + break; + } + } + + /* + * program SDRAM Timing Register 1, adding some delays + */ + program_tr1(); + + /* + * if ECC is enabled, initialize parity bits + */ + + return total_size; +} + +unsigned char spd_read(uchar chip, uint addr) { + unsigned char data[2]; + + if (i2c_read(chip, addr, 1, data, 1) == 0) + return data[0]; + else + return 0; +} + +void get_spd_info(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long dimm_found; + unsigned char num_of_bytes; + unsigned char total_size; + + dimm_found = FALSE; + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + num_of_bytes = 0; + total_size = 0; + + num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0); + total_size = spd_read(iic0_dimm_addr[dimm_num], 1); + + if ((num_of_bytes != 0) && (total_size != 0)) { + dimm_populated[dimm_num] = TRUE; + dimm_found = TRUE; +#if 0 + printf("DIMM slot %lu: populated\n", dimm_num); +#endif + } + else { + dimm_populated[dimm_num] = FALSE; +#if 0 + printf("DIMM slot %lu: Not populated\n", dimm_num); +#endif + } + } + + if (dimm_found == FALSE) { + printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); + hang(); + } +} + +void check_mem_type(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned char dimm_type; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); + switch (dimm_type) { + case 7: +#if 0 + printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num); +#endif + break; + default: + printf("ERROR: Unsupported DIMM detected in slot %lu.\n", + dimm_num); + printf("Only DDR SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + } + } + } +} + + +void check_volt_type(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long voltage_type; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8); + if (voltage_type != 0x04) { + printf("ERROR: DIMM %lu with unsupported voltage level.\n", + dimm_num); + hang(); + } + else { +#if 0 + printf("DIMM %lu voltage level supported.\n", dimm_num); +#endif + } + break; + } + } +} + +void program_cfg0(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long cfg0; + unsigned long ecc_enabled; + unsigned char ecc; + unsigned char attributes; + unsigned long data_width; + unsigned long dimm_32bit; + unsigned long dimm_64bit; + + /* + * get Memory Controller Options 0 data + */ + mfsdram(mem_cfg0, cfg0); + + /* + * clear bits + */ + cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK | + SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD | + SDRAM_CFG0_DMWD_MASK | + SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP); + + + /* + * FIXME: assume the DDR SDRAMs in both banks are the same + */ + ecc_enabled = TRUE; + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + ecc = spd_read(iic0_dimm_addr[dimm_num], 11); + if (ecc != 0x02) { + ecc_enabled = FALSE; + } + + /* + * program Registered DIMM Enable + */ + attributes = spd_read(iic0_dimm_addr[dimm_num], 21); + if ((attributes & 0x02) != 0x00) { + cfg0 |= SDRAM_CFG0_RDEN; + } + + /* + * program DDR SDRAM Data Width + */ + data_width = + (unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) + + (((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8); + if (data_width == 64 || data_width == 72) { + dimm_64bit = TRUE; + cfg0 |= SDRAM_CFG0_DMWD_64; + } + else if (data_width == 32 || data_width == 40) { + dimm_32bit = TRUE; + cfg0 |= SDRAM_CFG0_DMWD_32; + } + else { + printf("WARNING: DIMM with datawidth of %lu bits.\n", + data_width); + printf("Only DIMMs with 32 or 64 bit datawidths supported.\n"); + hang(); + } + break; + } + } + + /* + * program Memory Data Error Checking + */ + if (ecc_enabled == TRUE) { + cfg0 |= SDRAM_CFG0_MCHK_GEN; + } + else { + cfg0 |= SDRAM_CFG0_MCHK_NON; + } + + /* + * program Page Management Unit + */ + cfg0 |= SDRAM_CFG0_PMUD; + + /* + * program Memory Controller Options 0 + * Note: DCEN must be enabled after all DDR SDRAM controller + * configuration registers get initialized. + */ + mtsdram(mem_cfg0, cfg0); +} + +void program_cfg1(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long cfg1; + mfsdram(mem_cfg1, cfg1); + + /* + * Self-refresh exit, disable PM + */ + cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN); + + /* + * program Memory Controller Options 1 + */ + mtsdram(mem_cfg1, cfg1); +} + +void program_rtr (unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long bus_period_x_10; + unsigned long refresh_rate = 0; + unsigned char refresh_rate_type; + unsigned long refresh_interval; + unsigned long sdram_rtr; + PPC440_SYS_INFO sys_info; + + /* + * get the board info + */ + get_sys_info(&sys_info); + bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); + + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12); + switch (refresh_rate_type) { + case 0x00: + refresh_rate = 15625; + break; + case 0x011: + refresh_rate = 15625/4; + break; + case 0x02: + refresh_rate = 15625/2; + break; + case 0x03: + refresh_rate = 15626*2; + break; + case 0x04: + refresh_rate = 15625*4; + break; + case 0x05: + refresh_rate = 15625*8; + break; + default: + printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n", + dimm_num); + printf("Replace the DIMM module with a supported DIMM.\n"); + break; + } + + break; + } + } + + refresh_interval = refresh_rate * 10 / bus_period_x_10; + sdram_rtr = (refresh_interval & 0x3ff8) << 16; + + /* + * program Refresh Timer Register (SDRAM0_RTR) + */ + mtsdram(mem_rtr, sdram_rtr); +} + +void program_tr0 (unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long tr0; + unsigned char wcsbc; + unsigned char t_rp_ns; + unsigned char t_rcd_ns; + unsigned char t_ras_ns; + unsigned long t_rp_clk; + unsigned long t_ras_rcd_clk; + unsigned long t_rcd_clk; + unsigned long t_rfc_clk; + unsigned long plb_check; + unsigned char cas_bit; + unsigned long cas_index; + unsigned char cas_2_0_available; + unsigned char cas_2_5_available; + unsigned char cas_3_0_available; + unsigned long cycle_time_ns_x_10[3]; + unsigned long tcyc_3_0_ns_x_10; + unsigned long tcyc_2_5_ns_x_10; + unsigned long tcyc_2_0_ns_x_10; + unsigned long tcyc_reg; + unsigned long bus_period_x_10; + PPC440_SYS_INFO sys_info; + unsigned long residue; + + /* + * get the board info + */ + get_sys_info(&sys_info); + bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); + + /* + * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits + */ + mfsdram(mem_tr0, tr0); + tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK | + SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK | + SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK | + SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK); + + /* + * initialization + */ + wcsbc = 0; + t_rp_ns = 0; + t_rcd_ns = 0; + t_ras_ns = 0; + cas_2_0_available = TRUE; + cas_2_5_available = TRUE; + cas_3_0_available = TRUE; + tcyc_2_0_ns_x_10 = 0; + tcyc_2_5_ns_x_10 = 0; + tcyc_3_0_ns_x_10 = 0; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15); + t_rp_ns = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2; + t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2; + t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30); + cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); + + for (cas_index = 0; cas_index < 3; cas_index++) { + switch (cas_index) { + case 0: + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); + break; + case 1: + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23); + break; + default: + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25); + break; + } + + if ((tcyc_reg & 0x0F) >= 10) { + printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n", + dimm_num); + hang(); + } + + cycle_time_ns_x_10[cas_index] = + (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F); + } + + cas_index = 0; + + if ((cas_bit & 0x80) != 0) { + cas_index += 3; + } + else if ((cas_bit & 0x40) != 0) { + cas_index += 2; + } + else if ((cas_bit & 0x20) != 0) { + cas_index += 1; + } + + if (((cas_bit & 0x10) != 0) && (cas_index < 3)) { + tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; + cas_index++; + } + else { + if (cas_index != 0) { + cas_index++; + } + cas_3_0_available = FALSE; + } + + if (((cas_bit & 0x08) != 0) || (cas_index < 3)) { + tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index]; + cas_index++; + } + else { + if (cas_index != 0) { + cas_index++; + } + cas_2_5_available = FALSE; + } + + if (((cas_bit & 0x04) != 0) || (cas_index < 3)) { + tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; + cas_index++; + } + else { + if (cas_index != 0) { + cas_index++; + } + cas_2_0_available = FALSE; + } + + break; + } + } + + /* + * Program SD_WR and SD_WCSBC fields + */ + tr0 |= SDRAM_TR0_SDWR_2_CLK; /* Write Recovery: 2 CLK */ + switch (wcsbc) { + case 0: + tr0 |= SDRAM_TR0_SDWD_0_CLK; + break; + default: + tr0 |= SDRAM_TR0_SDWD_1_CLK; + break; + } + + /* + * Program SD_CASL field + */ + if ((cas_2_0_available == TRUE) && + (bus_period_x_10 >= tcyc_2_0_ns_x_10)) { + tr0 |= SDRAM_TR0_SDCL_2_0_CLK; + } + else if((cas_2_5_available == TRUE) && + (bus_period_x_10 >= tcyc_2_5_ns_x_10)) { + tr0 |= SDRAM_TR0_SDCL_2_5_CLK; + } + else if((cas_3_0_available == TRUE) && + (bus_period_x_10 >= tcyc_3_0_ns_x_10)) { + tr0 |= SDRAM_TR0_SDCL_3_0_CLK; + } + else { + printf("ERROR: No supported CAS latency with the installed DIMMs.\n"); + printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n"); + printf("Make sure the PLB speed is within the supported range.\n"); + hang(); + } + + /* + * Calculate Trp in clock cycles and round up if necessary + * Program SD_PTA field + */ + t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION; + plb_check = ONE_BILLION * t_rp_clk / t_rp_ns; + if (sys_info.freqPLB != plb_check) { + t_rp_clk++; + } + switch ((unsigned long)t_rp_clk) { + case 0: + case 1: + case 2: + tr0 |= SDRAM_TR0_SDPA_2_CLK; + break; + case 3: + tr0 |= SDRAM_TR0_SDPA_3_CLK; + break; + default: + tr0 |= SDRAM_TR0_SDPA_4_CLK; + break; + } + + /* + * Program SD_CTP field + */ + t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION; + plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns); + if (sys_info.freqPLB != plb_check) { + t_ras_rcd_clk++; + } + switch (t_ras_rcd_clk) { + case 0: + case 1: + case 2: + tr0 |= SDRAM_TR0_SDCP_2_CLK; + break; + case 3: + tr0 |= SDRAM_TR0_SDCP_3_CLK; + break; + case 4: + tr0 |= SDRAM_TR0_SDCP_4_CLK; + break; + default: + tr0 |= SDRAM_TR0_SDCP_5_CLK; + break; + } + + /* + * Program SD_LDF field + */ + tr0 |= SDRAM_TR0_SDLD_2_CLK; + + /* + * Program SD_RFTA field + * FIXME tRFC hardcoded as 75 nanoseconds + */ + t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75); + residue = sys_info.freqPLB % (ONE_BILLION / 75); + if (residue >= (ONE_BILLION / 150)) { + t_rfc_clk++; + } + switch (t_rfc_clk) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + tr0 |= SDRAM_TR0_SDRA_6_CLK; + break; + case 7: + tr0 |= SDRAM_TR0_SDRA_7_CLK; + break; + case 8: + tr0 |= SDRAM_TR0_SDRA_8_CLK; + break; + case 9: + tr0 |= SDRAM_TR0_SDRA_9_CLK; + break; + case 10: + tr0 |= SDRAM_TR0_SDRA_10_CLK; + break; + case 11: + tr0 |= SDRAM_TR0_SDRA_11_CLK; + break; + case 12: + tr0 |= SDRAM_TR0_SDRA_12_CLK; + break; + default: + tr0 |= SDRAM_TR0_SDRA_13_CLK; + break; + } + + /* + * Program SD_RCD field + */ + t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION; + plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns; + if (sys_info.freqPLB != plb_check) { + t_rcd_clk++; + } + switch (t_rcd_clk) { + case 0: + case 1: + case 2: + tr0 |= SDRAM_TR0_SDRD_2_CLK; + break; + case 3: + tr0 |= SDRAM_TR0_SDRD_3_CLK; + break; + default: + tr0 |= SDRAM_TR0_SDRD_4_CLK; + break; + } + +#if 0 + printf("tr0: %x\n", tr0); +#endif + mtsdram(mem_tr0, tr0); +} + +void program_tr1 (void) +{ + unsigned long tr0; + unsigned long tr1; + unsigned long cfg0; + unsigned long ecc_temp; + unsigned long dlycal; + unsigned long dly_val; + unsigned long i, j, k; + unsigned long bxcr_num; + unsigned long max_pass_length; + unsigned long current_pass_length; + unsigned long current_fail_length; + unsigned long current_start; + unsigned long rdclt; + unsigned long rdclt_offset; + long max_start; + long max_end; + long rdclt_average; + unsigned char window_found; + unsigned char fail_found; + unsigned char pass_found; + unsigned long * membase; + PPC440_SYS_INFO sys_info; + + /* + * get the board info + */ + get_sys_info(&sys_info); + + /* + * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits + */ + mfsdram(mem_tr1, tr1); + tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK | + SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK); + + mfsdram(mem_tr0, tr0); + if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) && + (sys_info.freqPLB > 100000000)) { + tr1 |= SDRAM_TR1_RDSS_TR2; + tr1 |= SDRAM_TR1_RDSL_STAGE3; + tr1 |= SDRAM_TR1_RDCD_RCD_1_2; + } + else { + tr1 |= SDRAM_TR1_RDSS_TR1; + tr1 |= SDRAM_TR1_RDSL_STAGE2; + tr1 |= SDRAM_TR1_RDCD_RCD_0_0; + } + + /* + * save CFG0 ECC setting to a temporary variable and turn ECC off + */ + mfsdram(mem_cfg0, cfg0); + ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK; + mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON); + + /* + * get the delay line calibration register value + */ + mfsdram(mem_dlycal, dlycal); + dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2; + + max_pass_length = 0; + max_start = 0; + max_end = 0; + current_pass_length = 0; + current_fail_length = 0; + current_start = 0; + rdclt_offset = 0; + window_found = FALSE; + fail_found = FALSE; + pass_found = FALSE; +#ifdef DEBUG + printf("Starting memory test "); +#endif + for (k = 0; k < NUMHALFCYCLES; k++) { + for (rdclt = 0; rdclt < dly_val; rdclt++) { + /* + * Set the timing reg for the test. + */ + mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt))); + + for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { + mtdcr(memcfga, mem_b0cr + (bxcr_num<<2)); + if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) { + /* Bank is enabled */ + membase = (unsigned long*) + (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK); + + /* + * Run the short memory test + */ + for (i = 0; i < NUMMEMTESTS; i++) { + for (j = 0; j < NUMMEMWORDS; j++) { + membase[j] = test[i][j]; + ppcDcbf((unsigned long)&(membase[j])); + } + + for (j = 0; j < NUMMEMWORDS; j++) { + if (membase[j] != test[i][j]) { + ppcDcbf((unsigned long)&(membase[j])); + break; + } + ppcDcbf((unsigned long)&(membase[j])); + } + + if (j < NUMMEMWORDS) { + break; + } + } + + /* + * see if the rdclt value passed + */ + if (i < NUMMEMTESTS) { + break; + } + } + } + + if (bxcr_num == MAXBXCR) { + if (fail_found == TRUE) { + pass_found = TRUE; + if (current_pass_length == 0) { + current_start = rdclt_offset + rdclt; + } + + current_fail_length = 0; + current_pass_length++; + + if (current_pass_length > max_pass_length) { + max_pass_length = current_pass_length; + max_start = current_start; + max_end = rdclt_offset + rdclt; + } + } + } + else { + current_pass_length = 0; + current_fail_length++; + + if (current_fail_length >= (dly_val>>2)) { + if (fail_found == FALSE) { + fail_found = TRUE; + } + else if (pass_found == TRUE) { + window_found = TRUE; + break; + } + } + } + } +#ifdef DEBUG + printf("."); +#endif + if (window_found == TRUE) { + break; + } + + tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; + rdclt_offset += dly_val; + } +#ifdef DEBUG + printf("\n"); +#endif + + /* + * make sure we find the window + */ + if (window_found == FALSE) { + printf("ERROR: Cannot determine a common read delay.\n"); + hang(); + } + + /* + * restore the orignal ECC setting + */ + mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp); + + /* + * set the SDRAM TR1 RDCD value + */ + tr1 &= ~SDRAM_TR1_RDCD_MASK; + if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) { + tr1 |= SDRAM_TR1_RDCD_RCD_1_2; + } + else { + tr1 |= SDRAM_TR1_RDCD_RCD_0_0; + } + + /* + * set the SDRAM TR1 RDCLT value + */ + tr1 &= ~SDRAM_TR1_RDCT_MASK; + while (max_end >= (dly_val<<1)) { + max_end -= (dly_val<<1); + max_start -= (dly_val<<1); + } + + rdclt_average = ((max_start + max_end) >> 1); + if (rdclt_average >= 0x60) + while(1); + + if (rdclt_average < 0) { + rdclt_average = 0; + } + + if (rdclt_average >= dly_val) { + rdclt_average -= dly_val; + tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; + } + tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average); + +#if 0 + printf("tr1: %x\n", tr1); +#endif + /* + * program SDRAM Timing Register 1 TR1 + */ + mtsdram(mem_tr1, tr1); +} + +unsigned long program_bxcr(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long bxcr_num; + unsigned long bank_base_addr; + unsigned long bank_size_bytes; + unsigned long cr; + unsigned long i; + unsigned long temp; + unsigned char num_row_addr; + unsigned char num_col_addr; + unsigned char num_banks; + unsigned char bank_size_id; + + + /* + * Set the BxCR regs. First, wipe out the bank config registers. + */ + for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { + mtdcr(memcfga, mem_b0cr + (bxcr_num << 2)); + mtdcr(memcfgd, 0x00000000); + } + + /* + * reset the bank_base address + */ + bank_base_addr = CFG_SDRAM_BASE; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3); + num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4); + num_banks = spd_read(iic0_dimm_addr[dimm_num], 5); + bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31); + + /* + * Set the SDRAM0_BxCR regs + */ + cr = 0; + bank_size_bytes = 4 * 1024 * 1024 * bank_size_id; + switch (bank_size_id) { + case 0x02: + cr |= SDRAM_BXCR_SDSZ_8; + break; + case 0x04: + cr |= SDRAM_BXCR_SDSZ_16; + break; + case 0x08: + cr |= SDRAM_BXCR_SDSZ_32; + break; + case 0x10: + cr |= SDRAM_BXCR_SDSZ_64; + break; + case 0x20: + cr |= SDRAM_BXCR_SDSZ_128; + break; + case 0x40: + cr |= SDRAM_BXCR_SDSZ_256; + break; + case 0x80: + cr |= SDRAM_BXCR_SDSZ_512; + break; + default: + printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", + dimm_num); + printf("ERROR: Unsupported value for the banksize: %d.\n", + bank_size_id); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + } + + switch (num_col_addr) { + case 0x08: + cr |= SDRAM_BXCR_SDAM_1; + break; + case 0x09: + cr |= SDRAM_BXCR_SDAM_2; + break; + case 0x0A: + cr |= SDRAM_BXCR_SDAM_3; + break; + case 0x0B: + cr |= SDRAM_BXCR_SDAM_4; + break; + default: + printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", + dimm_num); + printf("ERROR: Unsupported value for number of " + "column addresses: %d.\n", num_col_addr); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + } + + /* + * enable the bank + */ + cr |= SDRAM_BXCR_SDBE; + + /*------------------------------------------------------------------ + | This next section is hardware dependent and must be programmed + | to match the hardware. + +-----------------------------------------------------------------*/ + if (dimm_num == 0) { + for (i = 0; i < num_banks; i++) { + mtdcr(memcfga, mem_b0cr + (i << 2)); + temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | + SDRAM_BXCR_SDSZ_MASK | + SDRAM_BXCR_SDAM_MASK | + SDRAM_BXCR_SDBE); + cr |= temp; + cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; + mtdcr(memcfgd, cr); + bank_base_addr += bank_size_bytes; + } + } + else { + for (i = 0; i < num_banks; i++) { + mtdcr(memcfga, mem_b2cr + (i << 2)); + temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | + SDRAM_BXCR_SDSZ_MASK | + SDRAM_BXCR_SDAM_MASK | + SDRAM_BXCR_SDBE); + cr |= temp; + cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; + mtdcr(memcfgd, cr); + bank_base_addr += bank_size_bytes; + } + } + } + } + + return(bank_base_addr); +} + +void program_ecc (unsigned long num_bytes) +{ + unsigned long bank_base_addr; + unsigned long current_address; + unsigned long end_address; + unsigned long address_increment; + unsigned long cfg0; + + /* + * get Memory Controller Options 0 data + */ + mfsdram(mem_cfg0, cfg0); + + /* + * reset the bank_base address + */ + bank_base_addr = CFG_SDRAM_BASE; + + if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) { + mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | + SDRAM_CFG0_MCHK_GEN); + + if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) { + address_increment = 4; + } + else { + address_increment = 8; + } + + current_address = (unsigned long)(bank_base_addr); + end_address = (unsigned long)(bank_base_addr) + num_bytes; + + while (current_address < end_address) { + *((unsigned long*)current_address) = 0x00000000; + current_address += address_increment; + } + + mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | + SDRAM_CFG0_MCHK_CHK); + } +} + +#endif /* CONFIG_440 */ + +#endif /* CONFIG_SPD_EEPROM */ diff --git a/cpu/sa1100/serial.c b/cpu/sa1100/serial.c new file mode 100644 index 0000000..68bcd1f --- /dev/null +++ b/cpu/sa1100/serial.c @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * 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 <common.h> +#include <SA-1100.h> + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned int reg = 0; + + if (gd->baudrate == 1200) + reg = 191; + else if (gd->baudrate == 9600) + reg = 23; + else if (gd->baudrate == 19200) + reg = 11; + else if (gd->baudrate == 38400) + reg = 5; + else if (gd->baudrate == 57600) + reg = 3; + else if (gd->baudrate == 115200) + reg = 1; + else + hang (); + +#ifdef CONFIG_SERIAL1 + /* Wait until port is ready ... */ + while (Ser1UTSR1 & UTSR1_TBY) { + } + + /* init serial serial 1 */ + Ser1UTCR3 = 0x00; + Ser1UTSR0 = 0xff; + Ser1UTCR0 = (UTCR0_1StpBit | UTCR0_8BitData); + Ser1UTCR1 = 0; + Ser1UTCR2 = (u32) reg; + Ser1UTCR3 = (UTCR3_RXE | UTCR3_TXE); +#elif CONFIG_SERIAL3 + /* Wait until port is ready ... */ + while (Ser3UTSR1 & UTSR1_TBY) { + } + + /* init serial serial 3 */ + Ser3UTCR3 = 0x00; + Ser3UTSR0 = 0xff; + Ser3UTCR0 = (UTCR0_1StpBit | UTCR0_8BitData); + Ser3UTCR1 = 0; + Ser3UTCR2 = (u32) reg; + Ser3UTCR3 = (UTCR3_RXE | UTCR3_TXE); +#else +#error "Bad: you didn't configured serial ..." +#endif +} + + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + * + */ +int serial_init (void) +{ + serial_setbrg (); + + return (0); +} + + +/* + * Output a single byte to the serial port. + */ +void serial_putc (const char c) +{ +#ifdef CONFIG_SERIAL1 + /* wait for room in the tx FIFO on SERIAL1 */ + while ((Ser1UTSR0 & UTSR0_TFS) == 0); + + Ser1UTDR = c; +#elif CONFIG_SERIAL3 + /* wait for room in the tx FIFO on SERIAL3 */ + while ((Ser3UTSR0 & UTSR0_TFS) == 0); + + Ser3UTDR = c; +#endif + + /* If \n, also do \r */ + if (c == '\n') + serial_putc ('\r'); +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_tstc (void) +{ +#ifdef CONFIG_SERIAL1 + return Ser1UTSR1 & UTSR1_RNE; +#elif CONFIG_SERIAL3 + return Ser3UTSR1 & UTSR1_RNE; +#endif +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_getc (void) +{ +#ifdef CONFIG_SERIAL1 + while (!(Ser1UTSR1 & UTSR1_RNE)); + + return (char) Ser1UTDR & 0xff; +#elif CONFIG_SERIAL3 + while (!(Ser3UTSR1 & UTSR1_RNE)); + + return (char) Ser3UTDR & 0xff; +#endif +} + +void +serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} diff --git a/cpu/sa1100/start.S b/cpu/sa1100/start.S new file mode 100644 index 0000000..c0f30f5 --- /dev/null +++ b/cpu/sa1100/start.S @@ -0,0 +1,422 @@ +/* + * armboot - Startup Code for SA1100 CPU + * + * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> + * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + * Copyright (C) 2000 Wolfgang Denk <wd@denx.de> + * Copyright (c) 2001 Alex Züpke <azu@sysgo.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include <config.h> +#include <version.h> + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +/* + * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h) + */ +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * Note: _armboot_end_data and _armboot_end are defined + * by the (board-dependent) linker script. + * _armboot_end_data is the first usable FLASH address after armboot + */ +.globl _armboot_end_data +_armboot_end_data: + .word armboot_end_data +.globl _armboot_end +_armboot_end: + .word armboot_end + +/* + * _armboot_real_end is the first usable RAM address behind armboot + * and the various stacks + */ +.globl _armboot_real_end +_armboot_real_end: + .word 0x0badc0de + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de +#endif + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifdef CONFIG_INIT_CRITICAL + bl cpu_init_crit +#endif + +relocate: + /* + * relocate armboot to RAM + */ + adr r0, _start /* r0 <- current position of code */ + ldr r2, _armboot_start + ldr r3, _armboot_end + sub r2, r3, r2 /* r2 <- size of armboot */ + ldr r1, _TEXT_BASE /* r1 <- destination address */ + add r2, r0, r2 /* r2 <- source end address */ + + /* + * r0 = source address + * r1 = target address + * r2 = source end address + */ +copy_loop: + ldmia r0!, {r3-r10} + stmia r1!, {r3-r10} + cmp r0, r2 + ble copy_loop + + /* set up the stack */ + ldr r0, _armboot_end + add r0, r0, #CONFIG_STACKSIZE + sub sp, r0, #12 /* leave 3 words for abort-stack */ + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +/* Interupt-Controller base address */ +IC_BASE: .word 0x90050000 +#define ICMR 0x04 + + +/* Reset-Controller */ +RST_BASE: .word 0x90030000 +#define RSRR 0x00 +#define RCSR 0x04 + + +/* PWR */ +PWR_BASE: .word 0x90020000 +#define PSPR 0x08 +#define PPCR 0x14 +cpuspeed: .word CFG_CPUSPEED + + +cpu_init_crit: + /* + * mask all IRQs + */ + ldr r0, IC_BASE + mov r1, #0x00 + str r1, [r0, #ICMR] + + /* set clock speed */ + ldr r0, PWR_BASE + ldr r1, cpuspeed + str r1, [r0, #PPCR] + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a memsetup.S in your board directory. + */ + mov ip, lr + bl memsetup + mov lr, ip + + /* + * disable MMU stuff and enable I-cache + */ + mrc p15,0,r0,c1,c0 + bic r0, r0, #0x00002000 @ clear bit 13 (X) + bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM) + orr r0, r0, #0x00001000 @ set bit 12 (I) Icache + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + mcr p15,0,r0,c1,c0 + + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + mov pc, lr + + + + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + + ldr r2, _armboot_end + add r2, r2, #CONFIG_STACKSIZE + sub r2, r2, #8 + ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + .endm + + .macro irq_restore_user_regs + ldmia sp, {r0 - lr}^ @ Calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 @ return & move spsr_svc into cpsr + .endm + + .macro get_bad_stack + ldr r13, _armboot_end @ setup our mode stack + add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack + sub r13, r13, #8 + + str lr, [r13] @ save caller lr / spsr + mrs lr, spsr + str lr, [r13, #4] + + mov r13, #MODE_SVC @ prepare SVC-Mode + msr spsr_c, r13 + mov lr, pc + movs pc, lr + .endm + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + +#ifdef CONFIG_USE_IRQ + + .align 5 +irq: + get_irq_stack + irq_save_user_regs + bl do_irq + irq_restore_user_regs + + .align 5 +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + irq_restore_user_regs + +#else + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq + +#endif + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r0, RST_BASE + mov r1, #0x0 @ set bit 3-0 ... + str r1, [r0, #RCSR] @ ... to clear in RCSR + mov r1, #0x1 + str r1, [r0, #RSRR] @ and perform reset + b reset_cpu @ silly, but repeat endlessly diff --git a/disk/part_dos.c b/disk/part_dos.c new file mode 100644 index 0000000..8e71baa --- /dev/null +++ b/disk/part_dos.c @@ -0,0 +1,233 @@ +/* + * (C) Copyright 2001 + * Raymond Lo, lo@routefree.com + * 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 + */ + +/* + * Support for harddisk partitions. + * + * To be compatible with LinuxPPC and Apple we use the standard Apple + * SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#include <common.h> +#include <command.h> +#include <ide.h> +#include <cmd_disk.h> +#include "part_dos.h" + +#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 + */ +static inline int le32_to_int(unsigned char *le32) +{ + return ((le32[3] << 24) + + (le32[2] << 16) + + (le32[1] << 8) + + le32[0] + ); +} + +static inline int is_extended(int part_type) +{ + return (part_type == 0x5 || + part_type == 0xf || + part_type == 0x85); +} + +static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num) +{ + int lba_start = ext_part_sector + le32_to_int (p->start4); + int lba_size = le32_to_int (p->size4); + + printf ("%5d\t\t%10d\t%10d\t%2x%s\n", + part_num, lba_start, lba_size, p->sys_ind, + (is_extended (p->sys_ind) ? " Extd" : "")); +} + + + +int test_part_dos (block_dev_desc_t *dev_desc) +{ + unsigned char buffer[DEFAULT_SECTOR_SIZE]; + + 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); + } + return (0); +} + +/* Print a partition that is relative to its Extended partition table + */ +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 (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_desc->dev, ext_part_sector); + return; + } + if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || + buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { + printf ("bad MBR sector signature 0x%02x%02x\n", + buffer[DOS_PART_MAGIC_OFFSET], + buffer[DOS_PART_MAGIC_OFFSET + 1]); + return; + } + + /* Print all primary/logical partitions */ + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + for (i = 0; i < 4; i++, pt++) { + /* + * fdisk does not show the extended partitions that + * are not in the MBR + */ + + if ((pt->sys_ind != 0) && + (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) { + print_one_part (pt, ext_part_sector, part_num); + } + + /* Reverse engr the fdisk part# assignment rule! */ + if ((ext_part_sector == 0) || + (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) { + part_num++; + } + } + + /* Follows the extended partitions */ + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + for (i = 0; i < 4; i++, pt++) { + if (is_extended (pt->sys_ind)) { + int lba_start = le32_to_int (pt->start4) + relative; + + print_partition_extended (dev_desc, lba_start, + ext_part_sector == 0 ? lba_start + : relative, + part_num); + } + } + + return; +} + + +/* Print a partition that is relative to its Extended partition table + */ +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) +{ + unsigned char buffer[DEFAULT_SECTOR_SIZE]; + dos_partition_t *pt; + int i; + + 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_desc->dev, ext_part_sector); + return -1; + } + if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || + buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { + printf ("bad MBR sector signature 0x%02x%02x\n", + buffer[DOS_PART_MAGIC_OFFSET], + buffer[DOS_PART_MAGIC_OFFSET + 1]); + return -1; + } + + /* Print all primary/logical partitions */ + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + for (i = 0; i < 4; i++, pt++) { + /* + * fdisk does not show the extended partitions that + * are not in the MBR + */ + if (pt->sys_ind != 0 && part_num == which_part) { + info->blksz = 512; + info->start = ext_part_sector + le32_to_int (pt->start4); + info->size = le32_to_int (pt->size4); + switch(dev_desc->if_type) { + case IF_TYPE_IDE: + case IF_TYPE_ATAPI: + 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; + case IF_TYPE_USB: + sprintf (info->name, "usbd%c%d\n", 'a' + dev_desc->dev, part_num); + break; + case IF_TYPE_DOC: + sprintf (info->name, "docd%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, "U-Boot"); + return 0; + } + + /* Reverse engr the fdisk part# assignment rule! */ + if ((ext_part_sector == 0) || + (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) { + part_num++; + } + } + + /* Follows the extended partitions */ + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + for (i = 0; i < 4; i++, pt++) { + if (is_extended (pt->sys_ind)) { + int lba_start = le32_to_int (pt->start4) + relative; + + return get_partition_info_extended (dev_desc, lba_start, + ext_part_sector == 0 ? lba_start : relative, + part_num, which_part, info); + } + } + return -1; +} + +void print_part_dos (block_dev_desc_t *dev_desc) +{ + printf ("Partition Start Sector Num Sectors Type\n"); + print_partition_extended (dev_desc, 0, 0, 1); +} + +int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * 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_mac.c b/disk/part_mac.c new file mode 100644 index 0000000..ee9d170 --- /dev/null +++ b/disk/part_mac.c @@ -0,0 +1,251 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Support for harddisk partitions. + * + * To be compatible with LinuxPPC and Apple we use the standard Apple + * SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#include <common.h> +#include <command.h> +#include <ide.h> +#include <cmd_disk.h> +#include "part_mac.h" + +#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 +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 + + +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 (block_dev_desc_t *dev_desc) +{ + mac_driver_desc_t ddesc; + mac_partition_t mpart; + ulong i, n; + + 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 ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) || + (mpart.signature != MAC_PARTITION_MAGIC) ) { + return (-1); + } + /* update partition count */ + n = mpart.map_count; + } + return (0); +} + + +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_desc, &ddesc)) { + /* error reading Driver Desriptor Block, or no valid Signature */ + return; + } + + n = ddesc.blk_count; + + mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */ + /* round to 1 digit */ + mb.rem *= 10 * ddesc.blk_size; + mb.rem += 512 * 1024; + mb.rem /= 1024 * 1024; + + gb = ldiv(10 * mb.quot + mb.rem, 10240); + gb.rem += 512; + gb.rem /= 1024; + + + printf ("Block Size=%d, Number of Blocks=%d, " + "Total Capacity: %ld.%ld MB = %ld.%ld GB\n" + "DeviceType=0x%x, DeviceId=0x%x\n\n" + " #: type name" + " length base (size)\n", + ddesc.blk_size, + ddesc.blk_count, + mb.quot, mb.rem, gb.quot, gb.rem, + ddesc.dev_type, ddesc.dev_id + ); + + n = 1; /* assuming at least one partition */ + for (i=1; i<=n; ++i) { + ulong bytes; + char c; + + printf ("%4ld: ", i); + if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) { + printf ("** Can't read Partition Map on %d:%ld **\n", + 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_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature); + return; + } + + /* update partition count */ + n = mpart.map_count; + + c = 'k'; + bytes = mpart.block_count; + bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */ + if (bytes >= 1024) { + bytes >>= 10; + c = 'M'; + } + if (bytes >= 1024) { + bytes >>= 10; + c = 'G'; + } + + printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", + mpart.type, + mpart.name, + mpart.block_count, + mpart.start_block, + bytes, c + ); + } + + return; +} + + +/* + * Read Device Descriptor Block + */ +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p) +{ + if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) { + printf ("** Can't read Driver Desriptor Block **\n"); + return (-1); + } + + if (ddb_p->signature != MAC_DRIVER_MAGIC) { +#if 0 + printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n", + MAC_DRIVER_MAGIC, ddb_p->signature); +#endif + return (-1); + } + return (0); +} + +/* + * Read Partition Descriptor Block + */ +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p) +{ + int n = 1; + + for (;;) { + /* + * We must always read the descritpor block for + * partition 1 first since this is the only way to + * know how many partitions we have. + */ + 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_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_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature); + return (-1); + } + + if (n == part) + return (0); + + if ((part < 1) || (part > pdb_p->map_count)) { + printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n", + dev_desc->dev, part, + dev_desc->dev, + dev_desc->dev, pdb_p->map_count); + return (-1); + } + + /* update partition count */ + n = part; + } + + /* NOTREACHED */ +} + +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_desc, &ddesc)) { + return (-1); + } + + info->blksz = ddesc.blk_size; + + if (part_mac_read_pdb (dev_desc, part, &mpart)) { + return (-1); + } + + info->start = mpart.start_block; + info->size = mpart.block_count; + memcpy (info->type, mpart.type, sizeof(info->type)); + memcpy (info->name, mpart.name, sizeof(info->name)); + + return (0); +} + +#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_MAC_PARTITION */ diff --git a/disk/part_mac.h b/disk/part_mac.h new file mode 100644 index 0000000..0340fe8 --- /dev/null +++ b/disk/part_mac.h @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * See also Linux sources, fs/partitions/mac.h + * + * This file describes structures and values related to the standard + * Apple SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#ifndef _DISK_PART_MAC_H +#define _DISK_PART_MAC_H + +#define MAC_DRIVER_MAGIC 0x4552 + +/* + * Driver Descriptor Structure, in block 0. + * This block is (and shall remain) 512 bytes long. + * Note that there is an alignment problem for the driver descriptor map! + */ +typedef struct mac_driver_desc { + __u16 signature; /* expected to be MAC_DRIVER_MAGIC */ + __u16 blk_size; /* block size of device */ + __u32 blk_count; /* number of blocks on device */ + __u16 dev_type; /* device type */ + __u16 dev_id; /* device id */ + __u32 data; /* reserved */ + __u16 drvr_cnt; /* number of driver descriptor entries */ + __u16 drvr_map[247]; /* driver descriptor map */ +} mac_driver_desc_t; + +/* + * Device Driver Entry + * (Cannot be included in mac_driver_desc because of alignment problems) + */ +typedef struct mac_driver_entry { + __u32 block; /* block number of starting block */ + __u16 size; /* size of driver, in 512 byte blocks */ + __u16 type; /* OS Type */ +} mac_driver_entry_t; + + +#define MAC_PARTITION_MAGIC 0x504d + +/* type field value for A/UX or other Unix partitions */ +#define APPLE_AUX_TYPE "Apple_UNIX_SVR2" + +/* + * Each Partition Map entry (in blocks 1 ... N) has this format: + */ +typedef struct mac_partition { + __u16 signature; /* expected to be MAC_PARTITION_MAGIC */ + __u16 sig_pad; /* reserved */ + __u32 map_count; /* # blocks in partition map */ + __u32 start_block; /* abs. starting block # of partition */ + __u32 block_count; /* number of blocks in partition */ + uchar name[32]; /* partition name */ + uchar type[32]; /* string type description */ + __u32 data_start; /* rel block # of first data block */ + __u32 data_count; /* number of data blocks */ + __u32 status; /* partition status bits */ + __u32 boot_start; /* first block of boot code */ + __u32 boot_size; /* size of boot code, in bytes */ + __u32 boot_load; /* boot code load address */ + __u32 boot_load2; /* reserved */ + __u32 boot_entry; /* boot code entry point */ + __u32 boot_entry2; /* reserved */ + __u32 boot_cksum; /* boot code checksum */ + uchar processor[16]; /* Type of Processor */ + __u16 part_pad[188]; /* reserved */ +} mac_partition_t; + +#define MAC_STATUS_BOOTABLE 8 /* partition is bootable */ + +#endif /* _DISK_PART_MAC_H */ diff --git a/doc/README.PIP405 b/doc/README.PIP405 new file mode 100644 index 0000000..c5ccf18 --- /dev/null +++ b/doc/README.PIP405 @@ -0,0 +1,385 @@ +U-Boot 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_U_BOOT, 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_U_BOOT, IH_TYPE_FIRMWARE +- include/u-boot.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_U_BOOT, 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/u-boot.lds Linker description +- board/pip405/u-boot.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 u-boot.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 U_BOOT_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 U-Boot 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/u-boot.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 +"U_BOOT_VERSION __TIME__ DATE___ " String, to allows to identify intermidiate +and custom versions. +Changed files: +- cpu/ppc4xx/start.s + +Firmware Image: +--------------- +Added IH_OS_U_BOOT and IH_TYPE_FIRMWARE to the image definitions to allows the +U-Boot 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 U-Boot 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/doc/README.RPXlite b/doc/README.RPXlite new file mode 100644 index 0000000..25bf80b --- /dev/null +++ b/doc/README.RPXlite @@ -0,0 +1,887 @@ +# Porting U-Boot onto RPXlite board +# Written by Yoo. Jonghoon +# E-Mail : yooth@ipone.co.kr +# IP ONE Inc. + +# Since 2001. 1. 29 + +# Shell : bash +# Cross-compile tools : Montavista Hardhat +# Debugging tools : Windriver VisionProbe (PowerPC BDM) +# ppcboot ver. : ppcboot-0.8.1 + +############################################################### +# 1. Hardware setting +############################################################### + +1.1. Board, BDM settings + Install board, BDM, connect each other + +1.2. Save Register value + Boot with board-on monitor program and save the + register values with BDM. + +1.3. Configure flash programmer + Check flash memory area in the memory map. + 0xFFC00000 - 0xFFFFFFFF + + Boot monitor program is at + 0xFFF00000 + + You can program on-board flash memory with VisionClick + flash programmer. Set the target flash device as: + + 29DL800B + + (?) The flash memory device in the board *is* 29LV800B, + but I cannot program it with '29LV800B' option. + (in VisionClick flash programming tools) + I don't know why... + +1.4. Save boot monitor program *IMPORTANT* + Upload boot monitor program from board to file. + boot monitor program starts at 0xFFF00000 + +1.5. Test flash memory programming + Try to erase boot program in the flash memory, + and re-write them. + *WARNING* YOU MUST SAVE BOOT PROGRAM TO FILE + BEFORE ERASING FLASH + +############################################################### +# 2. U-Boot setting +############################################################### + +2.1. Download U-Boot tarball at + ftp://ftp.denx.de + (The latest version is ppcboot-0.8.1.tar.bz2) + + To extract the archive use the following syntax : + > bzip2 -cd ppcboot-0.8.1.tar.bz2 | tar xf - + +2.2. Add the following lines in '.profile' + export PATH=$PATH:/opt/hardhat/devkit/ppc/8xx/bin + +2.3. Make board specific config, for example: + > cd ppcboot-0.8.1 + > make TQM860L_config + + Now we can build ppcboot bin files. + After make all, you must see these files in your + ppcboot root directory. + + ppcboot + ppcboot.bin + ppcboot.srec + ppcboot.map + +2.4. Make your own board directory into the + ppcboot-0.8.1/board + and make your board-specific files here. + + For exmanple, tqm8xx files are composed of + .depend : Nothing + Makefile : To make config file + config.mk : Sets base address + flash.c : Flash memory control files + ppcboot.lds : linker(ld) script? (I don't know this yet) + tqm8xx.c : DRAM control and board check routines + + And, add your board config lines in the + ppcboot-0.8.1/Makefile + + Finally, add config_(your board).h file in the + ppcboot-0.8.1/include/ + + I've made board/rpxlite directory, and just copied + tqm8xx settings for now. + + Rebuild ppcboot for rpxlite board: + > make rpxlite_config + > make + +############################################################### +# 3. U-Boot porting +############################################################### + +3.1. My RPXlite files are based on tqm8xx board files. + > cd board + > cp -r tqm8xx RPXLITE + > cd RPXLITE + > mv tqm8xx.c RPXLITE.c + > cd ../../include + > cp config_tqm8xx.h config_RPXLITE.h + +3.2. Modified files are: + board/RPXLITE/RPXLITE.c /* DRAM-related routines */ + board/RPXLITE/flash.c /* flash-related routines */ + board/RPXLITE/config.mk /* set text base address */ + cpu/mpc8xx/serial.c /* board specific register setting */ + include/config_RPXLITE.h /* board specific registers */ + + See 'reg_config.txt' for register values in detail. + +############################################################### +# 4. Running Linux +############################################################### + + + + + + + + + +############################################################### +# Misc Information +############################################################### + +mem_config.txt: +=============== + +Flash memory device : AM29LV800BB (1Mx8Bit) x 4 device +manufacturer id : 01 (AMD) +device id : 5B (AM29LV800B) +size : 4Mbyte +sector # : 19 + +Sector information : + +number start addr. size +00 FFC0_0000 64 +01 FFC1_0000 32 +02 FFC1_8000 32 +03 FFC2_0000 128 +04 FFC4_0000 256 +05 FFC8_0000 256 +06 FFCC_0000 256 +07 FFD0_0000 256 +08 FFD4_0000 256 +09 FFD8_0000 256 +10 FFDC_0000 256 +11 FFE0_0000 256 +12 FFE4_0000 256 +13 FFE8_0000 256 +14 FFEC_0000 256 +15 FFF0_0000 256 +16 FFF4_0000 256 +17 FFF8_0000 256 +18 FFFC_0000 256 + + +reg_config.txt: +=============== + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* SIU (System Interface Unit) */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ + + +/*### IMMR */ +/*### Internal Memory Map Register */ +/*### Chap. 11.4.1 */ + + ISB = 0xFA20 /* Set the Immap base = 0xFA20 0000 */ + PARTNUM = 0x21 + MASKNUM = 0x00 + + => 0xFA20 2100 + +--------------------------------------------------------------------- + +/*### SIUMCR */ +/*### SIU Module Configuration Register */ +/*### Chap. 11.4.2 */ +/*### Offset : 0x0000 0000 */ + + EARB = 0 + EARP = 0 + DSHW = 0 + DBGC = 0 + DBPC = 0 + FRC = 0 + DLK = 0 + OPAR = 0 + PNCS = 0 + DPC = 0 + MPRE = 0 + MLRC = 10 /* ~KR/~RETRY/~IRQ4/SPKROUT functions as ~KR/~TRTRY */ + AEME = 0 + SEME = 0 + BSC = 0 + GB5E = 0 + B2DD = 0 + B3DD = 0 + + => 0x0000 0800 + +--------------------------------------------------------------------- + +/*### SYPCR */ +/*### System Protection Control Register */ +/*### Chap. 11.4.3 */ +/*### Offset : 0x0000 0004 */ + + SWTC = 0xFFFF /* SW watchdog timer count = 0xFFFF */ + BMT = 0x06 /* BUS monitoring timing */ + BME = 1 /* BUS monitor enable */ + SWF = 1 + SWE = 0 /* SW watchdog disable */ + SWRI = 0 + SWP = 1 + + => 0xFFFF 0689 + +--------------------------------------------------------------------- + +/*### TESR */ +/*### Transfer Error Status Register */ +/*### Chap. 11.4.4 */ +/*### Offset : 0x0000 0020 */ + + IEXT = 0 + ITMT = 0 + IPB = 0000 + DEXT = 0 + DTMT = 0 + DPB = 0000 + + => 0x0000 0000 + +--------------------------------------------------------------------- + +/*### SIPEND */ +/*### SIU Interrupt Pending Register */ +/*### Chap. 11.5.4.1 */ +/*### Offset : 0x0000 0010 */ + + IRQ0~IRQ7 = 0 + LVL0~LVL7 = 0 + + => 0x0000 0000 + +--------------------------------------------------------------------- + +/*### SIMASK */ +/*### SIU Interrupt Mask Register */ +/*### Chap. 11.5.4.2 */ +/*### Offset : 0x0000 0014 */ + + IRM0~IRM7 = 0 /* Mask all interrupts */ + LVL0~LVL7 = 0 + + => 0x0000 0000 + +--------------------------------------------------------------------- + +/*### SIEL */ +/*### SIU Interrupt Edge/Level Register */ +/*### Chap. 11.5.4.3 */ +/*### Offset : 0x0000 0018 */ + + ED0~ED7 = 0 /* Low level triggered */ + WMn0~WMn7 = 0 /* Not allowed to exit from low-power mode */ + + => 0x0000 0000 + +--------------------------------------------------------------------- + +/*### SIVEC */ +/*### SIU Interrupt Vector Register */ +/*### Chap. 11.5.4.4 */ +/*### Offset : 0x0000 001C */ + + INTC = 3C /* The lowest interrupt is pending..(?) */ + + => 0x3C00 0000 + +--------------------------------------------------------------------- + +/*### SWSR */ +/*### Software Service Register */ +/*### Chap. 11.7.1 */ +/*### Offset : 0x0000 001E */ + + SEQ = 0 + + => 0x0000 + +--------------------------------------------------------------------- + +/*### SDCR */ +/*### SDMA Configuration Register */ +/*### Chap. 20.2.1 */ +/*### Offset : 0x0000 0032 */ + + FRZ = 0 + RAID = 01 /* Priority level 5 (BR5) (normal operation) */ + + => 0x0000 0001 + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* UPMA (User Programmable Machine A) */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ + +/*### Chap. 16.6.4.1 */ +/*### Offset = 0x0000 017c */ + + T0 = CFFF CC24 /* Single Read */ + T1 = 0FFF CC04 + T2 = 0CAF CC04 + T3 = 03AF CC08 + T4 = 3FBF CC27 /* last */ + T5 = FFFF CC25 + T6 = FFFF CC25 + T7 = FFFF CC25 + T8 = CFFF CC24 /* Burst Read */ + T9 = 0FFF CC04 + T10 = 0CAF CC84 + T11 = 03AF CC88 + T12 = 3FBF CC27 /* last */ + T13 = FFFF CC25 + T14 = FFFF CC25 + T15 = FFFF CC25 + T16 = FFFF CC25 + T17 = FFFF CC25 + T18 = FFFF CC25 + T19 = FFFF CC25 + T20 = FFFF CC25 + T21 = FFFF CC25 + T22 = FFFF CC25 + T23 = FFFF CC25 + T24 = CFFF CC24 /* Single Write */ + T25 = 0FFF CC04 + T26 = 0CFF CC04 + T27 = 03FF CC00 + T28 = 3FFF CC27 /* last */ + T29 = FFFF CC25 + T30 = FFFF CC25 + T31 = FFFF CC25 + T32 = CFFF CC24 /* Burst Write */ + T33 = 0FFF CC04 + T34 = 0CFF CC80 + T35 = 03FF CC8C + T36 = 0CFF CC00 + T37 = 33FF CC27 /* last */ + T38 = FFFF CC25 + T39 = FFFF CC25 + T40 = FFFF CC25 + T41 = FFFF CC25 + T42 = FFFF CC25 + T43 = FFFF CC25 + T44 = FFFF CC25 + T45 = FFFF CC25 + T46 = FFFF CC25 + T47 = FFFF CC25 + T48 = C0FF CC24 /* Refresh */ + T49 = 03FF CC24 + T50 = 0FFF CC24 + T51 = 0FFF CC24 + T52 = 3FFF CC27 /* last */ + T53 = FFFF CC25 + T54 = FFFF CC25 + T55 = FFFF CC25 + T56 = FFFF CC25 + T57 = FFFF CC25 + T58 = FFFF CC25 + T59 = FFFF CC25 + T60 = FFFF CC25 /* Exception */ + T61 = FFFF CC25 + T62 = FFFF CC25 + T63 = FFFF CC25 + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* UPMB */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +--------------------------------------------------------------------- + +/*### Chap. 16.6.4.1 */ + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* MEMC */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +--------------------------------------------------------------------- + +/*### BR0 & OR0 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR0(0x0000 0100) & OR0(0x0000 0104) */ +/*### Flash memory */ + + BA = 1111 1110 0000 0000 0 /* Base addr = 0xFE00 0000 */ + AT = 000 + PS = 00 + PARE = 0 + WP = 0 + MS = 0 /* GPCM */ + V = 1 /* Valid */ + + => 0xFE00 0001 + + AM = 1111 1110 0000 0000 0 /* 32MBytes */ + ATM = 000 + CSNT/SAM = 0 + ACS/G5LA,G5LS = 00 + BIH = 1 /* Burst inhibited */ + SCY = 0100 /* cycle length = 4 */ + SETA = 0 + TRLX = 0 + EHTR = 0 + + => 0xFE00 0140 + +/*### BR1 & OR1 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR1(0x0000 0108) & OR1(0x0000 010C) */ +/*### SDRAM */ + + BA = 0000 0000 0000 0000 0 /* Base addr = 0x0000 0000 */ + AT = 000 + PS = 00 + PARE = 0 + WP = 0 + MS = 1 /* UPMA */ + V = 1 /* Valid */ + + => 0x0000 0081 + + AM = 1111 1110 0000 0000 /* 32MBytes */ + ATM = 000 + CSNT/SAM = 1 + ACS/G5LA,G5LS = 11 + BIH = 0 + SCY = 0000 /* cycle length = 0 */ + SETA = 0 + TRLX = 0 + EHTR = 0 + + => 0xFE00 0E00 + +/*### BR2 & OR2 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR2(0x0000 0110) & OR2(0x0000 0114) */ + + BR2 & OR2 = 0x0000 0000 /* Not used */ + +/*### BR3 & OR3 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR3(0x0000 0118) & OR3(0x0000 011C) */ +/*### BCSR */ + + BA = 1111 1010 0100 0000 0 /* Base addr = 0xFA40 0000 */ + AT = 000 + PS = 00 + PARE = 0 + WP = 0 + MS = 0 /* GPCM */ + V = 1 /* Valid */ + + => 0xFA40 0001 + + AM = 1111 1111 0111 1111 1 /* (?) */ + ATM = 000 + CSNT/SAM = 1 + ACS/G5LA,G5LS = 00 + BIH = 1 /* Burst inhibited */ + SCY = 0001 /* cycle length = 1 */ + SETA = 0 + TRLX = 0 + + => 0xFF7F 8910 + +/*### BR4 & OR4 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR4(0x0000 0120) & OR4(0x0000 0124) */ +/*### NVRAM & SRAM */ + + BA = 1111 1010 0000 0000 0 /* Base addr = 0xFA00 0000 */ + AT = 000 + PS = 01 + PARE = 0 + WP = 0 + MS = 0 /* GPCM */ + V = 1 /* Valid */ + + => 0xFA00 0401 + + AM = 1111 1111 1111 1000 0 /* 8MByte */ + ATM = 000 + CSNT/SAM = 1 + ACS/G5LA,G5LS = 00 + BIH = 1 /* Burst inhibited */ + SCY = 0111 /* cycle length = 7 */ + SETA = 0 + TRLX = 0 + + => 0xFFF8 0970 + +/*### BR5 & OR5 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR2(0x0000 0128) & OR2(0x0000 012C) */ + + BR5 & OR5 = 0x0000 0000 /* Not used */ + +/*### BR6 & OR6 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR2(0x0000 0130) & OR2(0x0000 0134) */ + + BR6 & OR6 = 0x0000 0000 /* Not used */ + +/*### BR7 & OR7 */ +/*### Base Registers & Option Registers */ +/*### Chap. 16.4.1 & 16.4.2 */ +/*### Offset : BR7(0x0000 0138) & OR7(0x0000 013C) */ + + BR7 & OR7 = 0x0000 0000 /* Not used */ + +/*### MAR */ +/*### Memory Address Register */ +/*### Chap. 16.4.7 */ +/*### Offset : 0x0000 0164 */ + + MA = External memory address + +/*### MCR */ +/*### Memory Command Register */ +/*### Chap. 16.4.5 */ +/*### Offset : 0x0000 0168 */ + + OP = xx /* Command op code */ + UM = 1 /* Select UPMA */ + MB = 001 /* Select CS1 */ + MCLF = xxxx /* Loop times */ + MAD = xx xxxx /* Memory array index */ + +/*### MAMR */ +/*### Machine A Mode Register */ +/*### Chap. 16.4.4 */ +/*### Offset : 0x0000 0170 */ + + PTA = 0101 1000 + PTAE = 1 /* Periodic timer A enabled */ + AMA = 010 + DSA = 00 + G0CLA = 000 + GPLA4DIS = 1 + RLFA = 0100 + WLFA = 0011 + TLFA = 0000 + + => 0x58A0 1430 + +/*### MBMR */ +/*### Machine B Mode Register */ +/*### Chap. 16.4.4 */ +/*### Offset : 0x0000 0174 */ + + PTA = 0100 1110 + PTAE = 0 /* Periodic timer B disabled */ + AMA = 000 + DSA = 00 + G0CLA = 000 + GPLA4DIS = 1 + RLFA = 0000 + WLFA = 0000 + TLFA = 0000 + + => 0x4E00 1000 + +/*### MSTAT */ +/*### Memory Status Register */ +/*### Chap. 16.4.3 */ +/*### Offset : 0x0000 0178 */ + + PER0~PER7 = Parity error + WPER = Write protection error + + => 0x0000 + +/*### MPTPR */ +/*### Memory Periodic Timer Prescaler Register */ +/*### Chap. 16.4.8 */ +/*### Offset : 0x0000 017A */ + + PTP = 0000 1000 /* Divide by 8 */ + + => 0x0800 + +/*### MDR */ +/*### Memory Data Register */ +/*### Chap. 16.4.6 */ +/*### Offset : 0x0000 017C */ + + MD = Memory data contains the RAM array word + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* TIMERS */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +--------------------------------------------------------------------- + +/*### TBREFx */ +/*### Timebase Reference Registers */ +/*### Chap. 11.9.2 */ +/*### Offset : TBREFF0(0x0000 0204)/TBREFF1(0x0000 0208) */ +/*### (Locked) */ + + TBREFF0 = 0xFFFF FFFF + TBREFF1 = 0xFFFF FFFF + +--------------------------------------------------------------------- + +/*### TBSCR */ +/*### Timebase Status and Control Registers */ +/*### Chap. 11.9.3 */ +/*### Offset : 0x0000 0200 */ +/*### (Locked) */ + + TBIRQ = 00000000 + REF0 = 0 + REF1 = 0 + REFE0 = 0 /* Reference interrupt disable */ + REFE1 = 0 + TBF = 1 + TBE = 1 /* Timebase enable */ + + => 0x0003 + +--------------------------------------------------------------------- + +/*### RTCSC */ +/*### Real-Time Clock Status and Control Registers */ +/*### Chap. 11.10.1 */ +/*### Offset : 0x0000 0220 */ +/*### (Locked) */ + + RTCIRQ = 00000000 + SEC = 1 + ALR = 0 + 38K = 0 /* PITRTCLK is driven by 32.768KHz */ + SIE = 0 + ALE = 0 + RTF = 0 + RTE = 1 /* Real-Time clock enabled */ + + => 0x0081 + +--------------------------------------------------------------------- + +/*### RTC */ +/*### Real-Time Clock Registers */ +/*### Chap. 11.10.2 */ +/*### Offset : 0x0000 0224 */ +/*### (Locked) */ + + RTC = Real time clock measured in second + +--------------------------------------------------------------------- + +/*### RTCAL */ +/*### Real-Time Clock Alarm Registers */ +/*### Chap. 11.10.3 */ +/*### Offset : 0x0000 022C */ +/*### (Locked) */ + + ALARM = 0xFFFF FFFF + +--------------------------------------------------------------------- + +/*### RTSEC */ +/*### Real-Time Clock Alarm Second Registers */ +/*### Chap. 11.10.4 */ +/*### Offset : 0x0000 0228 */ +/*### (Locked) */ + + COUNTER = Counter bits(fraction of a second) + +--------------------------------------------------------------------- + +/*### PISCR */ +/*### Periodic Interrupt Status and Control Register */ +/*### Chap. 11.11.1 */ +/*### Offset : 0x0000 0240 */ +/*### (Locked) */ + + PIRQ = 0 + PS = 0 /* Write 1 to clear */ + PIE = 0 + PITF = 1 + PTE = 0 /* PIT disabled */ + +--------------------------------------------------------------------- + +/*### PITC */ +/*### PIT Count Register */ +/*### Chap. 11.11.2 */ +/*### Offset : 0x0000 0244 */ +/*### (Locked) */ + + PITC = PIT count + +--------------------------------------------------------------------- + +/*### PITR */ +/*### PIT Register */ +/*### Chap. 11.11.3 */ +/*### Offset : 0x0000 0248 */ +/*### (Locked) */ + + PIT = PIT count /* Read only */ + + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* CLOCKS */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +--------------------------------------------------------------------- + + +--------------------------------------------------------------------- + +/*### SCCR */ +/*### System Clock and Reset Control Register */ +/*### Chap. 15.6.1 */ +/*### Offset : 0x0000 0280 */ +/*### (Locked) */ + + COM = 11 /* Clock output disabled */ + TBS = 1 /* Timebase frequency source is GCLK2 divided by 16 */ + RTDIV = 0 /* The clock is divided by 4 */ + RTSEL = 0 /* OSCM(Crystal oscillator) is selected */ + CRQEN = 0 + PRQEN = 0 + EBDF = 00 /* CLKOUT is GCLK2 divided by 1 */ + DFSYNC = 00 /* Divided by 1 (normal operation) */ + DFBRG = 00 /* Divided by 1 (normal operation) */ + DFNL = 000 + DFNH = 000 + + => 0x6200 0000 + +--------------------------------------------------------------------- + +/*### PLPRCR */ +/*### PLL, Low-Power, and Reset Control Register */ +/*### Chap. 15.6.2 */ +/*### Offset : 0x0000 0284 */ +/*### (Locked) */ + + MF = 0x005 /* 48MHz (?) ( = 8MHz * (MF+1) ) */ + SPLSS = 0 + TEXPS = 0 + TMIST = 0 + CSRC = 0 /* The general system clock is generated by the DFNH field */ + LPM = 00 /* Normal high/normal low mode */ + CSR = 0 + LOLRE = 0 + FIOPD = 0 + + => 0x0050 0000 + +--------------------------------------------------------------------- + +/*### RSR */ +/*### Reset Status Register */ +/*### Chap. 12.2 */ +/*### Offset : 0x0000 0288 */ +/*### (Locked) */ + + EHRS = External hard reset + ESRS = External soft reset + LLRS = Loss-of-lock reset + SWRS = Software watchdog reset + CSRS = Check stop reset + DBHRS = Debug port hard reset + DBSRS = Debug port soft reset + JTRS = JTAG reset + + + +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +/* DMA */ +/* */ +/*------------------------------------------------------------------- */ +/*------------------------------------------------------------------- */ +--------------------------------------------------------------------- + +/*### SDSR */ +/*### SDMA Status Register */ +/*### Chap. 20.2.2 */ +/*### Offset : 0x0000 0908 */ + + SBER = 0 /* SDMA channel bus error */ + DSP2 = 0 /* DSP chain2 (Tx) interrupt */ + DSP1 = 0 /* DSP chain1 (Rx) interrupt */ + + => 0x00 + +/*### SDMR */ +/*### SDMA Mask Register */ +/*### Chap. 20.2.3 */ +/*### Offset : 0x0000 090C */ + + SBER = 0 + DSP2 = 0 + DSP1 = 0 /* All interrupts are masked */ + + => 0x00 + +/*### SDAR */ +/*### SDMA Address Register */ +/*### Chap. 20.2.4 */ +/*### Offset : 0x0000 0904 */ + + AR = 0xxxxx xxxx /* current system address */ + + => 0xFA20 23AC + +/*### IDSRx */ +/*### IDMA Status Register */ +/*### Chap. 20.3.3.2 */ +/*### Offset : IDSR1(0x0000 0910) & IDSR2(0x0000 0918) */ + + AD = 0 + DONE = 0 + OB = 0 + + => 0x00 + +/*### IDMRx */ +/*### IDMA Mask Register */ +/*### Chap. 20.3.3.3 */ +/*### Offset : IDMR1(0x0000 0914) & IDMR2(0x0000 091C) */ + + AD = 0 + DONE = 0 + OB = 0 + diff --git a/doc/README.Sandpoint8240 b/doc/README.Sandpoint8240 new file mode 100644 index 0000000..5cb79b3 --- /dev/null +++ b/doc/README.Sandpoint8240 @@ -0,0 +1,397 @@ +The port was tested on a Sandpoint 8240 X3 board, with U-Boot +installed in the flash memory of the CPU card. Please use the +following DIP switch settings: + +Motherboard: + +SW1.1: on SW1.2: on SW1.3: on SW1.4: on +SW1.5: on SW1.6: on SW1.7: on SW1.8: on + +SW2.1: on SW2.2: on SW2.3: on SW2.4: on +SW2.5: on SW2.6: on SW2.7: on SW2.8: on + + +CPU Card: + +SW2.1: OFF SW2.2: OFF SW2.3: on SW2.4: on +SW2.5: OFF SW2.6: OFF SW2.7: OFF SW2.8: OFF + +SW3.1: OFF SW3.2: on SW3.3: OFF SW3.4: OFF +SW3.5: on SW3.6: OFF SW3.7: OFF SW3.8: on + + + +The followind detailed description of installation and initial steps +with U-Boot and QNX was provided by Jim Sandoz <sandoz@lucent.com>: + + +Directions for installing U-Boot on Sandpoint+Unity8240 +using the Abatron BDI2000 BDM/JTAG debugger ... + +Background and Reference info: +http://u-boot.sourceforge.net/ +http://www.abatron.ch/ +http://www.abatron.ch/BDI/bdihw.html +http://www.abatron.ch/DataSheets/BDI2000.pdf +http://www.abatron.ch/Manuals/ManGdbCOP-2000C.pdf +http://e-www.motorola.com/collateral/SPX3UM.pdf +http://e-www.motorola.com/collateral/UNITYX4CONFIG.pdf + + + +Connection Diagram: + =========== + === ===== |----- | +| | <---------------> | | | | | +|PC | rs232 | BDI |=============[] | | +| | |2000 | BDM probe | | | +| | <---------------> | | |----- | + === ethernet ===== | | + | | + =========== + Sandpoint X3 with + Unity 8240 proc + + +PART 1) + DIP Switch Settings: + +Sandpoint X3 8240 processor board DIP switch settings, with +U-Boot to be installed in the flash memory of the CPU card: + +Motorola Sandpoint X3 Motherboard: +SW1.1: on SW1.2: on SW1.3: on SW1.4: on +SW1.5: on SW1.6: on SW1.7: on SW1.8: on +SW2.1: on SW2.2: on SW2.3: on SW2.4: on +SW2.5: on SW2.6: on SW2.7: on SW2.8: on + +Motorola Unity 8240 CPU Card: +SW2.1: OFF SW2.2: OFF SW2.3: on SW2.4: on +SW2.5: OFF SW2.6: OFF SW2.7: OFF SW2.8: OFF +SW3.1: OFF SW3.2: on SW3.3: OFF SW3.4: OFF +SW3.5: on SW3.6: OFF SW3.7: OFF SW3.8: on + + +PART 2) + Connect the BDI2000 Cable to the Sandpoint/Unity 8240: + +BDM Pin 1 on the Unity 8240 processor board is towards the +PCI PMC connectors, or away from the socketed SDRAM, i.e.: + + ==================== + | ---------------- | + | | SDRAM | | + | | | | + | ---------------- | + | |~| | + | |B| ++++++ | + | |D| + uP + | + | |M| +8240+ | + | ~ 1 ++++++ | + | | + | | + | | + | PMC conn ====== | + | ===== ====== | + | | + ==================== + + +PART 3) + Setting up the BDI2000, and preparing for TCP/IP network comms: + +Connect the BDI2000 to the PC using the supplied serial cable. +Download the BDI2000 software and install it using setup.exe. + +[Note: of course you can also use the Linux command line tool +"bdisetup" to configure your BDI2000 - the sources are included on +the floppy disk that comes with your BDI2000. Just in case you don't +have any Windows PC's - like me :-) -- wd ] + +Power up the BDI2000; then follow directions to assign the IP +address and related network information. Note that U-Boot +will be loaded to the Sandpoint via tftp. You need to either +use the Abatron-provided tftp application or provide a tftp +server (e.g. Linux/Solaris/*BSD) somewhere on your network. +Once the IP address etc are assigned via the RS232 port, +further communication with the BDI2000 will happen via the +ethernet connection. + +PART 4) + Making a TCP/IP network connection to the Abatron BDI2000: + +Telnet to the Abatron BDI2000. Assuming that all of the +networking info was loaded via RS232 correctly, you will see +the following (scrolling): + +- TARGET: waiting for target Vcc +- TARGET: waiting for target Vcc + + +PART 5) + Power up the target Sandpoint: +If the BDM connections are correct, the following will now appear: + +- TARGET: waiting for target Vcc +- TARGET: waiting for target Vcc +- TARGET: processing power-up delay +- TARGET: processing user reset request +- BDI asserts HRESET +- Reset JTAG controller passed +- Bypass check: 0x55 => 0xAA +- Bypass check: 0x55 => 0xAA +- JTAG exists check passed +- Target PVR is 0x00810101 +- COP status is 0x01 +- Check running state passed +- BDI scans COP freeze command +- BDI removes HRESET +- COP status is 0x05 +- Check stopped state passed +- Check LSRL length passed +- BDI sets breakpoint at 0xFFF00100 +- BDI resumes program execution +- Waiting for target stop passed +- TARGET: Target PVR is 0x00810101 +- TARGET: reseting target passed +- TARGET: processing target startup .... +- TARGET: processing target startup passed +BDI> + + +PART 6) + Erase the current contents of the flash memory: + +BDI>era 0xFFF00000 + Erasing flash at 0xfff00000 + Erasing flash passed +BDI>era 0xFFF04000 + Erasing flash at 0xfff04000 + Erasing flash passed +BDI>era 0xFFF06000 + Erasing flash at 0xfff06000 + Erasing flash passed +BDI>era 0xFFF08000 + Erasing flash at 0xfff08000 + Erasing flash passed +BDI>era 0xFFF10000 + Erasing flash at 0xfff10000 + Erasing flash passed +BDI>era 0xFFF20000 + Erasing flash at 0xfff20000 + Erasing flash passed + + +PART 7) + Program the flash memory with the U-Boot image: + +BDI>prog 0xFFF00000 u-boot.bin bin + Programming u-boot.bin , please wait .... + Programming flash passed + + +PART 8) + Connect PC to Sandpoint: +Using a crossover serial cable, attach the PC serial port to the +Sandpoint's COM1. Set communications parameters to 8N1 / 9600 baud. + + +PART 9) + Reset the Unity and begin U-Boot execution: + +BDI>reset +- TARGET: processing user reset request +- TARGET: Target PVR is 0x00810101 +- TARGET: reseting target passed +- TARGET: processing target init list .... +- TARGET: processing target init list passed + +BDI>go + +Now see output from U-Boot running, sent via serial port: + +U-Boot 1.1.4 (Jan 23 2002 - 18:29:19) + +CPU: MPC8240 Revision 1.1 at 264 MHz: 16 kB I-Cache 16 kB D-Cache +Board: Sandpoint 8240 Unity +DRAM: 64 MB +FLASH: 2 MB +PCI: scanning bus0 ... + bus dev fn venID devID class rev MBAR0 MBAR1 IPIN ILINE + 00 00 00 1057 0003 060000 13 00000008 00000000 01 00 + 00 0b 00 10ad 0565 060100 10 00000000 00000000 00 00 + 00 0f 00 8086 1229 020000 08 80000000 80000001 01 00 +In: serial +Out: serial +Err: serial +=> + + +PART 10) + Set and save any required environmental variables, examples of some: + +=> setenv ethaddr 00:03:47:97:D0:79 +=> setenv bootfile your_qnx_image_here +=> setenv hostname sandpointX +=> setenv netmask 255.255.255.0 +=> setenv ipaddr 192.168.0.11 +=> setenv serverip 192.168.0.10 +=> setenv gatewayip=192.168.0.1 +=> saveenv +Saving Enviroment to Flash... +Un-Protected 1 sectors +Erasing Flash... + done +Erased 1 sectors +Writing to Flash... done +Protected 1 sectors +=> + +**** Example environment: **** + +=> printenv +baudrate=9600 +bootfile=telemetry +hostname=sp1 +ethaddr=00:03:47:97:E4:6B +load=tftp 100000 u-boot.bin +update=protect off all;era FFF00000 FFF3FFFF;cp.b 100000 FFF00000 $(filesize);saveenv +filesize=1f304 +gatewayip=145.17.228.1 +netmask=255.255.255.0 +ipaddr=145.17.228.42 +serverip=145.17.242.46 +stdin=serial +stdout=serial +stderr=serial + +Environment size: 332/8188 bytes +=> + +here's some text useful stuff for cut-n-paste: +setenv hostname sandpoint1 +setenv netmask 255.255.255.0 +setenv ipaddr 145.17.228.81 +setenv serverip 145.17.242.46 +setenv gatewayip 145.17.228.1 +saveenv + +PART 11) + Test U-Boot by tftp'ing new U-Boot, overwriting current: + +=> protect off all +Un-Protect Flash Bank # 1 +=> tftp 100000 u-boot.bin +eth: Intel i82559 PCI EtherExpressPro @0x80000000(bus=0, device=15, func=0) +ARP broadcast 1 +TFTP from server 145.17.242.46; our IP address is 145.17.228.42; sending through + gateway 145.17.228.1 +Filename 'u-boot.bin'. +Load address: 0x100000 +Loading: ######################### +done +Bytes transferred = 127628 (1f28c hex) +=> era all +Erase Flash Bank # 1 + done +Erase Flash Bank # 2 - missing +=> cp.b 0x100000 FFF00000 1f28c +Copy to Flash... done +=> saveenv +Saving Enviroment to Flash... +Un-Protected 1 sectors +Erasing Flash... + done +Erased 1 sectors +Writing to Flash... done +Protected 1 sectors +=> reset + +You can put these commands into some environment variables; + +=> setenv load tftp 100000 u-boot.bin +=> setenv update protect off all\;era FFF00000 FFF3FFFF\;cp.b 100000 FFF00000 \$(filesize)\;saveenv +=> saveenv + +Then you just have to type "run load" then "run update" + +=> run load +eth: Intel i82559 PCI EtherExpressPro @0x80000000(bus=0, device=15, func=0) +ARP broadcast 1 +TFTP from server 145.17.242.46; our IP address is 145.17.228.42; sending through + gateway 145.17.228.1 +Filename 'u-boot.bin'. +Load address: 0x100000 +Loading: ######################### +done +Bytes transferred = 127748 (1f304 hex) +=> run update +Un-Protect Flash Bank # 1 +Un-Protect Flash Bank # 2 +Erase Flash from 0xfff00000 to 0xfff3ffff + done +Erased 7 sectors +Copy to Flash... done +Saving Enviroment to Flash... +Un-Protected 1 sectors +Erasing Flash... + done +Erased 1 sectors +Writing to Flash... done +Protected 1 sectors +=> + + +PART 12) + Load OS image (ELF format) via U-Boot using tftp + + +=> tftp 800000 sandpoint-simple.elf +eth: Intel i82559 PCI EtherExpressPro @0x80000000(bus=0, device=15, func=0) +ARP broadcast 1 +TFTP from server 145.17.242.46; our IP address is 145.17.228.42; sending through + gateway 145.17.228.1 +Filename 'sandpoint-simple.elf'. +Load address: 0x800000 +Loading: ################################################################# + ################################################################# + ################################################################# + ######################## +done +Bytes transferred = 1120284 (11181c hex) +==> + +PART 13) + Begin OS image execution: (note that unless you have the +serial parameters of your OS image set to 9600 (i.e. same as +the U-Boot binary) you will get garbage here until you change +the serial communications speed. + +=> bootelf 800000 +Loading @ 0x001f0100 (1120028 bytes) +## Starting application at 0x001f1d28 ... +Replace init_hwinfo() with a board specific version + +Loading QNX6.... + +Header size=0x0000009c, Total Size=0x000005c0, #Cpu=1, Type=1 +<...loader and kernel messages snipped...> + +Welcome to Neutrino on the Sandpoint +# + + +other information: + +CVS Retrieval Notes: + +U-Boot's SourceForge CVS repository can be checked out +through anonymous (pserver) CVS with the following +instruction set. The module you wish to check out must +be specified as the modulename. When prompted for a +password for anonymous, simply press the Enter key. + +cvs -d:pserver:anonymous@cvs.u-boot.sourceforge.net:/cvsroot/u-boot login + +cvs -z6 -d:pserver:anonymous@cvs.u-boot.sourceforge.net:/cvsroot/u-boot co -P u-boot + diff --git a/drivers/3c589.c b/drivers/3c589.c new file mode 100644 index 0000000..541f93b --- /dev/null +++ b/drivers/3c589.c @@ -0,0 +1,522 @@ +/*------------------------------------------------------------------------ + . 3c589.c + . This is a driver for 3Com's 3C589 (Etherlink III) PCMCIA Ethernet device. + . + . (C) Copyright 2002 + . Sysgo Real-Time Solutions, GmbH <www.elinos.com> + . Rolf Offermanns <rof@sysgo.de> + . + . 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 <common.h> +#include <command.h> +#include <net.h> + +#ifdef CONFIG_DRIVER_3C589 + +#include "3c589.h" + + +/* Use power-down feature of the chip */ +#define POWER_DOWN 0 + +#define NO_AUTOPROBE + +static const char version[] = + "Your ad here! :P\n"; + + +#undef EL_DEBUG + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long int dword; +/*------------------------------------------------------------------------ + . + . Configuration options, for the experienced user to change. + . + -------------------------------------------------------------------------*/ + +/* + . Wait time for memory to be free. This probably shouldn't be + . tuned that much, as waiting for this means nothing else happens + . in the system +*/ +#define MEMORY_WAIT_TIME 16 + + +#if (EL_DEBUG > 2 ) +#define PRINTK3(args...) printf(args) +#else +#define PRINTK3(args...) +#endif + +#if EL_DEBUG > 1 +#define PRINTK2(args...) printf(args) +#else +#define PRINTK2(args...) +#endif + +#ifdef EL_DEBUG +#define PRINTK(args...) printf(args) +#else +#define PRINTK(args...) +#endif + +#define outb(args...) mmio_outb(args) +#define mmio_outb(value, addr) (*((volatile byte *)(addr)) = value) + +#define inb(args...) mmio_inb(args) +#define mmio_inb(addr) (*((volatile byte *)(addr))) + +#define outw(args...) mmio_outw(args) +#define mmio_outw(value, addr) (*((volatile word *)(addr)) = value) + +#define inw(args...) mmio_inw(args) +#define mmio_inw(addr) (*((volatile word *)(addr))) + +#define outsw(args...) mmio_outsw(args) +#define mmio_outsw(r,b,l) ({ int __i; \ + word *__b2; \ + __b2 = (word *) b; \ + for (__i = 0; __i < l; __i++) { \ + mmio_outw( *(__b2 + __i), r); \ + } \ + }) + +#define insw(args...) mmio_insw(args) +#define mmio_insw(r,b,l) ({ int __i ; \ + word *__b2; \ + __b2 = (word *) b; \ + for (__i = 0; __i < l; __i++) { \ + *(__b2 + __i) = mmio_inw(r); \ + mmio_inw(0); \ + }; \ + }) + +/*------------------------------------------------------------------------ + . + . The internal workings of the driver. If you are changing anything + . here with the 3Com stuff, you should have the datasheet and know + . what you are doing. + . + -------------------------------------------------------------------------*/ +#define EL_BASE_ADDR 0x20000000 + + +/* Offsets from base I/O address. */ +#define EL3_DATA 0x00 +#define EL3_TIMER 0x0a +#define EL3_CMD 0x0e +#define EL3_STATUS 0x0e + +#define EEPROM_READ 0x0080 + +#define EL3WINDOW(win_num) mmio_outw(SelectWindow + (win_num), EL_BASE_ADDR + EL3_CMD) + +/* The top five bits written to EL3_CMD are a command, the lower + 11 bits are the parameter, if applicable. */ +enum c509cmd { + TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, + RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11, + TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, + FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, + SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, + SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, + StatsDisable = 22<<11, StopCoax = 23<<11, +}; + +enum c509status { + IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, + TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, + IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000 +}; + +/* The SetRxFilter command accepts the following classes: */ +enum RxFilter { + RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 +}; + +/* Register window 1 offsets, the window used in normal operation. */ +#define TX_FIFO 0x00 +#define RX_FIFO 0x00 +#define RX_STATUS 0x08 +#define TX_STATUS 0x0B +#define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */ + + +/* + Read a word from the EEPROM using the regular EEPROM access register. + Assume that we are in register window zero. +*/ +static word read_eeprom(dword ioaddr, int index) +{ + int i; + outw(EEPROM_READ + index, ioaddr + 0xa); + /* Reading the eeprom takes 162 us */ + for (i = 1620; i >= 0; i--) + if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0) + break; + return inw(ioaddr + 0xc); +} + +static void el_get_mac_addr( unsigned char *mac_addr ) +{ + int i; + union + { + word w; + unsigned char b[2]; + } wrd; + unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13; + GO_WINDOW(0); + VX_BUSY_WAIT; + for (i = 0; i < 3; i++) + { + wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i); +#ifdef __BIG_ENDIAN + mac_addr[2*i] = wrd.b[0]; + mac_addr[2*i+1] = wrd.b[1]; +#else + mac_addr[2*i] = wrd.b[1]; + mac_addr[2*i+1] = wrd.b[0]; +#endif + } + GO_WINDOW(old_window); + VX_BUSY_WAIT; +} + + +#if EL_DEBUG > 1 +static void print_packet( byte * buf, int length ) +{ + int i; + int remainder; + int lines; + + PRINTK2("Packet of length %d \n", length ); + + lines = length / 16; + remainder = length % 16; + + for ( i = 0; i < lines ; i ++ ) { + int cur; + + for ( cur = 0; cur < 8; cur ++ ) { + byte a, b; + + a = *(buf ++ ); + b = *(buf ++ ); + PRINTK2("%02x%02x ", a, b ); + } + PRINTK2("\n"); + } + for ( i = 0; i < remainder/2 ; i++ ) { + byte a, b; + + a = *(buf ++ ); + b = *(buf ++ ); + PRINTK2("%02x%02x ", a, b ); + } + PRINTK2("\n"); +} +#endif /* EL_DEBUG > 1 */ + + + +/************************************************************************** +ETH_RESET - Reset adapter +***************************************************************************/ +static void el_reset(bd_t *bd) +{ + /*********************************************************** + Reset 3Com 595 card + *************************************************************/ + /* QUICK HACK + * - adjust timing for 3c589 + * - enable io for PCMCIA */ + outw(0x0004, 0xa0000018); + udelay(100); + outw(0x0041, 0x28010000); + udelay(100); + + /* issue global reset */ + outw(GLOBAL_RESET, BASE + VX_COMMAND); + + /* must wait for at least 1ms */ + udelay(100000000); + + /* set mac addr */ + { + unsigned char *mac_addr = bd->bi_enetaddr; + int i; + + el_get_mac_addr( mac_addr ); + + GO_WINDOW(2); + VX_BUSY_WAIT; + + printf("3C589 MAC Addr.: "); + for (i = 0; i < 6; i++) + { + printf("%02x", mac_addr[i]); + outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i); + VX_BUSY_WAIT; + } + printf("\n\n"); + } + + /* set RX filter */ + outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + VX_COMMAND); + VX_BUSY_WAIT; + + + /* set irq mask and read_zero */ + outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE | + S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND); + VX_BUSY_WAIT; + + outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE | + S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND); + VX_BUSY_WAIT; + + /* enable TP Linkbeat */ + GO_WINDOW(4); + VX_BUSY_WAIT; + + outw( ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE); + VX_BUSY_WAIT; + + +/* + * Attempt to get rid of any stray interrupts that occured during + * configuration. On the i386 this isn't possible because one may + * already be queued. However, a single stray interrupt is + * unimportant. + */ + + outw(ACK_INTR | 0xff, BASE + VX_COMMAND); + VX_BUSY_WAIT; + + /* enable TX and RX */ + outw( RX_ENABLE, BASE + VX_COMMAND ); + VX_BUSY_WAIT; + + outw( TX_ENABLE, BASE + VX_COMMAND ); + VX_BUSY_WAIT; + + + /* print the diag. regs. */ + PRINTK2("Diag. Regs\n"); + PRINTK2("--> MEDIA_TYPE: %04x\n", inw(BASE + VX_W4_MEDIA_TYPE)); + PRINTK2("--> NET_DIAG: %04x\n", inw(BASE + VX_W4_NET_DIAG)); + PRINTK2("--> FIFO_DIAG: %04x\n", inw(BASE + VX_W4_FIFO_DIAG)); + PRINTK2("--> CTRLR_STATUS: %04x\n", inw(BASE + VX_W4_CTRLR_STATUS)); + PRINTK2("\n\n"); + + /* enter working mode */ + GO_WINDOW(1); + VX_BUSY_WAIT; + + /* wait for another 1ms */ + udelay(100000000); +} + + +/*----------------------------------------------------------------- + . + . The driver can be entered at any of the following entry points. + . + .------------------------------------------------------------------ */ + +extern int eth_init(bd_t *bd); +extern void eth_halt(void); +extern int eth_rx(void); +extern int eth_send(volatile void *packet, int length); + + +/* + ------------------------------------------------------------ + . + . Internal routines + . + ------------------------------------------------------------ +*/ + +int eth_init(bd_t *bd) +{ + el_reset(bd); + return 0; +} + +void eth_halt() { + return; +} + +#define EDEBUG 1 + + +/************************************************************************** +ETH_POLL - Wait for a frame +***************************************************************************/ + +int eth_rx() +{ + word status, rx_status, packet_size; + + VX_BUSY_WAIT; + + status = inw( BASE + VX_STATUS ); + + if ( (status & S_RX_COMPLETE) == 0 ) return 0; /* nothing to do */ + + /* Packet waiting -> check RX_STATUS */ + rx_status = inw( BASE + VX_W1_RX_STATUS ); + + if ( rx_status & ERR_RX ) + { + /* error in packet -> discard */ + PRINTK("[ERROR] Invalid packet -> discarding\n"); + PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK); + PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1)); + PRINTK("[ERROR] Invalid packet -> discarding\n"); + outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND ); + return 0; + } + + /* correct pack. waiting in fifo */ + packet_size = rx_status & RX_BYTES_MASK; + + PRINTK("Correct packet waiting in fifo, size: %d\n", packet_size); + + { + volatile word *packet_start = (word *)(BASE + VX_W1_RX_PIO_RD_1); + word *RcvBuffer = (word *)(NetRxPackets[0]); + int wcount = 0; + + for (wcount = 0; wcount < (packet_size >> 1); wcount++) + { + *RcvBuffer++ = *(packet_start); + } + + /* handle odd packets */ + if ( packet_size & 1 ) + { + *RcvBuffer++ = *(packet_start); + } + } + + /* fifo should now be empty (besides the padding bytes) */ + if ( ((*((word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK) > 3 ) + { + PRINTK("[ERROR] Fifo not empty after packet read (remaining pkts: %d)\n", + (((*(word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK)); + } + + /* discard packet */ + *((word *)(BASE + VX_COMMAND)) = RX_DISCARD_TOP_PACK; + + /* Pass Packets to upper Layer */ + NetReceive(NetRxPackets[0], packet_size); + return packet_size; +} + + + +/************************************************************************** +ETH_TRANSMIT - Transmit a frame +***************************************************************************/ +static char padmap[] = { + 0, 3, 2, 1}; + + +int eth_send(volatile void *packet, int length) { + int pad; + int status; + volatile word *buf = (word *)packet; + int dummy = 0; + + /* padding stuff */ + pad = padmap[length & 3]; + + PRINTK("eth_send(), length: %d\n", length); + /* drop acknowledgements */ + while(( status=inb(EL_BASE_ADDR + VX_W1_TX_STATUS) )& TXS_COMPLETE ) { + if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) { + outw(TX_RESET, EL_BASE_ADDR + VX_COMMAND); + outw(TX_ENABLE, EL_BASE_ADDR + VX_COMMAND); + PRINTK("Bad status, resetting and reenabling transmitter\n"); + } + + outb(0x0, EL_BASE_ADDR + VX_W1_TX_STATUS); + } + + + while (inw(EL_BASE_ADDR + VX_W1_FREE_TX) < length + pad + 4) { + /* no room in FIFO */ + if (dummy == 0) + { + PRINTK("No room in FIFO, waiting...\n"); + dummy++; + } + + } + + PRINTK(" ---> FIFO ready\n"); + + + outw(length, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1); + + /* Second dword meaningless */ + outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1); + +#if EL_DEBUG > 1 + print_packet((byte *)buf, length); +#endif + + /* write packet */ + { + unsigned int i, totw; + + totw = ((length + 1) >> 1); + PRINTK("Buffer: (totw = %d)\n", totw); + for (i = 0; i < totw; i++) { + outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1); + udelay(10); + } + if(totw & 1) + { /* pad to double word length */ + outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1); + udelay(10); + } + PRINTK("\n\n"); + } + + /* wait for Tx complete */ + PRINTK("Waiting for Tx to complete...\n"); + while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0) + { + udelay(10); + } + PRINTK(" ---> Tx completed, status = 0x%04x\n", status); + + return length; +} + + + +#endif /* CONFIG_DRIVER_3C589 */ diff --git a/drivers/bcm570x_autoneg.c b/drivers/bcm570x_autoneg.c new file mode 100644 index 0000000..1818c6a --- /dev/null +++ b/drivers/bcm570x_autoneg.c @@ -0,0 +1,444 @@ +/******************************************************************************/ +/* */ +/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2001 Broadcom */ +/* Corporation. */ +/* All rights reserved. */ +/* */ +/* 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, located in the file LICENSE. */ +/* */ +/* History: */ +/******************************************************************************/ +#if !defined(CONFIG_NET_MULTI) +#if INCLUDE_TBI_SUPPORT +#include "bcm570x_autoneg.h" +#include "bcm570x_mm.h" + + + +/******************************************************************************/ +/* Description: */ +/* */ +/* Return: */ +/******************************************************************************/ +void +MM_AnTxConfig( + PAN_STATE_INFO pAnInfo) +{ + PLM_DEVICE_BLOCK pDevice; + + pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext; + + REG_WR(pDevice, MacCtrl.TxAutoNeg, (LM_UINT32) pAnInfo->TxConfig.AsUSHORT); + + pDevice->MacMode |= MAC_MODE_SEND_CONFIGS; + REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode); +} + + + +/******************************************************************************/ +/* Description: */ +/* */ +/* Return: */ +/******************************************************************************/ +void +MM_AnTxIdle( + PAN_STATE_INFO pAnInfo) +{ + PLM_DEVICE_BLOCK pDevice; + + pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext; + + pDevice->MacMode &= ~MAC_MODE_SEND_CONFIGS; + REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode); +} + + + +/******************************************************************************/ +/* Description: */ +/* */ +/* Return: */ +/******************************************************************************/ +char +MM_AnRxConfig( + PAN_STATE_INFO pAnInfo, + unsigned short *pRxConfig) +{ + PLM_DEVICE_BLOCK pDevice; + LM_UINT32 Value32; + char Retcode; + + Retcode = AN_FALSE; + + pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext; + + Value32 = REG_RD(pDevice, MacCtrl.Status); + if(Value32 & MAC_STATUS_RECEIVING_CFG) + { + Value32 = REG_RD(pDevice, MacCtrl.RxAutoNeg); + *pRxConfig = (unsigned short) Value32; + + Retcode = AN_TRUE; + } + + return Retcode; +} + + + +/******************************************************************************/ +/* Description: */ +/* */ +/* Return: */ +/******************************************************************************/ +void +AutonegInit( + PAN_STATE_INFO pAnInfo) +{ + unsigned long j; + + for(j = 0; j < sizeof(AN_STATE_INFO); j++) + { + ((unsigned char *) pAnInfo)[j] = 0; + } + + /* Initialize the default advertisement register. */ + pAnInfo->mr_adv_full_duplex = 1; + pAnInfo->mr_adv_sym_pause = 1; + pAnInfo->mr_adv_asym_pause = 1; + pAnInfo->mr_an_enable = 1; +} + + + +/******************************************************************************/ +/* Description: */ +/* */ +/* Return: */ +/******************************************************************************/ +AUTONEG_STATUS +Autoneg8023z( + PAN_STATE_INFO pAnInfo) +{ + unsigned short RxConfig; + unsigned long Delta_us; + AUTONEG_STATUS AnRet; + + /* Get the current time. */ + if(pAnInfo->State == AN_STATE_UNKNOWN) + { + pAnInfo->RxConfig.AsUSHORT = 0; + pAnInfo->CurrentTime_us = 0; + pAnInfo->LinkTime_us = 0; + pAnInfo->AbilityMatchCfg = 0; + pAnInfo->AbilityMatchCnt = 0; + pAnInfo->AbilityMatch = AN_FALSE; + pAnInfo->IdleMatch = AN_FALSE; + pAnInfo->AckMatch = AN_FALSE; + } + + /* Increment the timer tick. This function is called every microsecon. */ +/* pAnInfo->CurrentTime_us++; */ + + /* Set the AbilityMatch, IdleMatch, and AckMatch flags if their */ + /* corresponding conditions are satisfied. */ + if(MM_AnRxConfig(pAnInfo, &RxConfig)) + { + if(RxConfig != pAnInfo->AbilityMatchCfg) + { + pAnInfo->AbilityMatchCfg = RxConfig; + pAnInfo->AbilityMatch = AN_FALSE; + pAnInfo->AbilityMatchCnt = 0; + } + else + { + pAnInfo->AbilityMatchCnt++; + if(pAnInfo->AbilityMatchCnt > 1) + { + pAnInfo->AbilityMatch = AN_TRUE; + pAnInfo->AbilityMatchCfg = RxConfig; + } + } + + if(RxConfig & AN_CONFIG_ACK) + { + pAnInfo->AckMatch = AN_TRUE; + } + else + { + pAnInfo->AckMatch = AN_FALSE; + } + + pAnInfo->IdleMatch = AN_FALSE; + } + else + { + pAnInfo->IdleMatch = AN_TRUE; + + pAnInfo->AbilityMatchCfg = 0; + pAnInfo->AbilityMatchCnt = 0; + pAnInfo->AbilityMatch = AN_FALSE; + pAnInfo->AckMatch = AN_FALSE; + + RxConfig = 0; + } + + /* Save the last Config. */ + pAnInfo->RxConfig.AsUSHORT = RxConfig; + + /* Default return code. */ + AnRet = AUTONEG_STATUS_OK; + + /* Autoneg state machine as defined in 802.3z section 37.3.1.5. */ + switch(pAnInfo->State) + { + case AN_STATE_UNKNOWN: + if(pAnInfo->mr_an_enable || pAnInfo->mr_restart_an) + { + pAnInfo->CurrentTime_us = 0; + pAnInfo->State = AN_STATE_AN_ENABLE; + } + + /* Fall through.*/ + + case AN_STATE_AN_ENABLE: + pAnInfo->mr_an_complete = AN_FALSE; + pAnInfo->mr_page_rx = AN_FALSE; + + if(pAnInfo->mr_an_enable) + { + pAnInfo->LinkTime_us = 0; + pAnInfo->AbilityMatchCfg = 0; + pAnInfo->AbilityMatchCnt = 0; + pAnInfo->AbilityMatch = AN_FALSE; + pAnInfo->IdleMatch = AN_FALSE; + pAnInfo->AckMatch = AN_FALSE; + + pAnInfo->State = AN_STATE_AN_RESTART_INIT; + } + else + { + pAnInfo->State = AN_STATE_DISABLE_LINK_OK; + } + break; + + case AN_STATE_AN_RESTART_INIT: + pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us; + pAnInfo->mr_np_loaded = AN_FALSE; + + pAnInfo->TxConfig.AsUSHORT = 0; + MM_AnTxConfig(pAnInfo); + + AnRet = AUTONEG_STATUS_TIMER_ENABLED; + + pAnInfo->State = AN_STATE_AN_RESTART; + + /* Fall through.*/ + + case AN_STATE_AN_RESTART: + /* Get the current time and compute the delta with the saved */ + /* link timer. */ + Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us; + if(Delta_us > AN_LINK_TIMER_INTERVAL_US) + { + pAnInfo->State = AN_STATE_ABILITY_DETECT_INIT; + } + else + { + AnRet = AUTONEG_STATUS_TIMER_ENABLED; + } + break; + + case AN_STATE_DISABLE_LINK_OK: + AnRet = AUTONEG_STATUS_DONE; + break; + + case AN_STATE_ABILITY_DETECT_INIT: + /* Note: in the state diagram, this variable is set to */ + /* mr_adv_ability<12>. Is this right?. */ + pAnInfo->mr_toggle_tx = AN_FALSE; + + /* Send the config as advertised in the advertisement register. */ + pAnInfo->TxConfig.AsUSHORT = 0; + pAnInfo->TxConfig.D5_FD = pAnInfo->mr_adv_full_duplex; + pAnInfo->TxConfig.D6_HD = pAnInfo->mr_adv_half_duplex; + pAnInfo->TxConfig.D7_PS1 = pAnInfo->mr_adv_sym_pause; + pAnInfo->TxConfig.D8_PS2 = pAnInfo->mr_adv_asym_pause; + pAnInfo->TxConfig.D12_RF1 = pAnInfo->mr_adv_remote_fault1; + pAnInfo->TxConfig.D13_RF2 = pAnInfo->mr_adv_remote_fault2; + pAnInfo->TxConfig.D15_NP = pAnInfo->mr_adv_next_page; + + MM_AnTxConfig(pAnInfo); + + pAnInfo->State = AN_STATE_ABILITY_DETECT; + + break; + + case AN_STATE_ABILITY_DETECT: + if(pAnInfo->AbilityMatch == AN_TRUE && + pAnInfo->RxConfig.AsUSHORT != 0) + { + pAnInfo->State = AN_STATE_ACK_DETECT_INIT; + } + + break; + + case AN_STATE_ACK_DETECT_INIT: + pAnInfo->TxConfig.D14_ACK = 1; + MM_AnTxConfig(pAnInfo); + + pAnInfo->State = AN_STATE_ACK_DETECT; + + /* Fall through. */ + + case AN_STATE_ACK_DETECT: + if(pAnInfo->AckMatch == AN_TRUE) + { + if((pAnInfo->RxConfig.AsUSHORT & ~AN_CONFIG_ACK) == + (pAnInfo->AbilityMatchCfg & ~AN_CONFIG_ACK)) + { + pAnInfo->State = AN_STATE_COMPLETE_ACK_INIT; + } + else + { + pAnInfo->State = AN_STATE_AN_ENABLE; + } + } + else if(pAnInfo->AbilityMatch == AN_TRUE && + pAnInfo->RxConfig.AsUSHORT == 0) + { + pAnInfo->State = AN_STATE_AN_ENABLE; + } + + break; + + case AN_STATE_COMPLETE_ACK_INIT: + /* Make sure invalid bits are not set. */ + if(pAnInfo->RxConfig.bits.D0 || pAnInfo->RxConfig.bits.D1 || + pAnInfo->RxConfig.bits.D2 || pAnInfo->RxConfig.bits.D3 || + pAnInfo->RxConfig.bits.D4 || pAnInfo->RxConfig.bits.D9 || + pAnInfo->RxConfig.bits.D10 || pAnInfo->RxConfig.bits.D11) + { + AnRet = AUTONEG_STATUS_FAILED; + break; + } + + /* Set up the link partner advertisement register. */ + pAnInfo->mr_lp_adv_full_duplex = pAnInfo->RxConfig.D5_FD; + pAnInfo->mr_lp_adv_half_duplex = pAnInfo->RxConfig.D6_HD; + pAnInfo->mr_lp_adv_sym_pause = pAnInfo->RxConfig.D7_PS1; + pAnInfo->mr_lp_adv_asym_pause = pAnInfo->RxConfig.D8_PS2; + pAnInfo->mr_lp_adv_remote_fault1 = pAnInfo->RxConfig.D12_RF1; + pAnInfo->mr_lp_adv_remote_fault2 = pAnInfo->RxConfig.D13_RF2; + pAnInfo->mr_lp_adv_next_page = pAnInfo->RxConfig.D15_NP; + + pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us; + + pAnInfo->mr_toggle_tx = !pAnInfo->mr_toggle_tx; + pAnInfo->mr_toggle_rx = pAnInfo->RxConfig.bits.D11; + pAnInfo->mr_np_rx = pAnInfo->RxConfig.D15_NP; + pAnInfo->mr_page_rx = AN_TRUE; + + pAnInfo->State = AN_STATE_COMPLETE_ACK; + AnRet = AUTONEG_STATUS_TIMER_ENABLED; + + break; + + case AN_STATE_COMPLETE_ACK: + if(pAnInfo->AbilityMatch == AN_TRUE && + pAnInfo->RxConfig.AsUSHORT == 0) + { + pAnInfo->State = AN_STATE_AN_ENABLE; + break; + } + + Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us; + + if(Delta_us > AN_LINK_TIMER_INTERVAL_US) + { + if(pAnInfo->mr_adv_next_page == 0 || + pAnInfo->mr_lp_adv_next_page == 0) + { + pAnInfo->State = AN_STATE_IDLE_DETECT_INIT; + } + else + { + if(pAnInfo->TxConfig.bits.D15 == 0 && + pAnInfo->mr_np_rx == 0) + { + pAnInfo->State = AN_STATE_IDLE_DETECT_INIT; + } + else + { + AnRet = AUTONEG_STATUS_FAILED; + } + } + } + + break; + + case AN_STATE_IDLE_DETECT_INIT: + pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us; + + MM_AnTxIdle(pAnInfo); + + pAnInfo->State = AN_STATE_IDLE_DETECT; + + AnRet = AUTONEG_STATUS_TIMER_ENABLED; + + break; + + case AN_STATE_IDLE_DETECT: + if(pAnInfo->AbilityMatch == AN_TRUE && + pAnInfo->RxConfig.AsUSHORT == 0) + { + pAnInfo->State = AN_STATE_AN_ENABLE; + break; + } + + Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us; + if(Delta_us > AN_LINK_TIMER_INTERVAL_US) + { +#if 0 +/* if(pAnInfo->IdleMatch == AN_TRUE) */ +/* { */ +#endif + pAnInfo->State = AN_STATE_LINK_OK; +#if 0 +/* } */ +/* else */ +/* { */ +/* AnRet = AUTONEG_STATUS_FAILED; */ +/* break; */ +/* } */ +#endif + } + + break; + + case AN_STATE_LINK_OK: + pAnInfo->mr_an_complete = AN_TRUE; + pAnInfo->mr_link_ok = AN_TRUE; + AnRet = AUTONEG_STATUS_DONE; + + break; + + case AN_STATE_NEXT_PAGE_WAIT_INIT: + break; + + case AN_STATE_NEXT_PAGE_WAIT: + break; + + default: + AnRet = AUTONEG_STATUS_FAILED; + break; + } + + return AnRet; +} +#endif /* INCLUDE_TBI_SUPPORT */ + +#endif /* !defined(CONFIG_NET_MULTI) */ diff --git a/drivers/cs8900.h b/drivers/cs8900.h new file mode 100644 index 0000000..0a35ba6 --- /dev/null +++ b/drivers/cs8900.h @@ -0,0 +1,256 @@ +/* + * Cirrus Logic CS8900A Ethernet + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * Copyright (C) 1999 Ben Williamson <benw@pobox.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is loaded into SRAM in bootstrap mode, where it waits + * for commands on UART1 to read and write memory, jump to code etc. + * A design goal for this program is to be entirely independent of the + * target board. Anything with a CL-PS7111 or EP7211 should be able to run + * this code in bootstrap mode. All the board specifics can be handled on + * the host. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <asm/types.h> +#include <config.h> + +#ifdef CONFIG_DRIVER_CS8900 + +/* although the registers are 16 bit, they are 32-bit aligned on the + EDB7111. so we have to read them as 32-bit registers and ignore the + upper 16-bits. i'm not sure if this holds for the EDB7211. */ + +#ifdef CS8900_BUS16 + /* 16 bit aligned registers, 16 bit wide */ + #define CS8900_REG u16 + #define CS8900_OFF 0x02 + #define CS8900_BUS16_0 *(volatile u8 *)(CS8900_BASE+0x00) + #define CS8900_BUS16_1 *(volatile u8 *)(CS8900_BASE+0x01) +#elif CS8900_BUS32 + /* 32 bit aligned registers, 16 bit wide (we ignore upper 16 bits) */ + #define CS8900_REG u32 + #define CS8900_OFF 0x04 +#else + #error unknown bussize ... +#endif + +#define CS8900_RTDATA *(volatile CS8900_REG *)(CS8900_BASE+0x00*CS8900_OFF) +#define CS8900_TxCMD *(volatile CS8900_REG *)(CS8900_BASE+0x02*CS8900_OFF) +#define CS8900_TxLEN *(volatile CS8900_REG *)(CS8900_BASE+0x03*CS8900_OFF) +#define CS8900_ISQ *(volatile CS8900_REG *)(CS8900_BASE+0x04*CS8900_OFF) +#define CS8900_PPTR *(volatile CS8900_REG *)(CS8900_BASE+0x05*CS8900_OFF) +#define CS8900_PDATA *(volatile CS8900_REG *)(CS8900_BASE+0x06*CS8900_OFF) + + +#define ISQ_RxEvent 0x04 +#define ISQ_TxEvent 0x08 +#define ISQ_BufEvent 0x0C +#define ISQ_RxMissEvent 0x10 +#define ISQ_TxColEvent 0x12 +#define ISQ_EventMask 0x3F + +/* packet page register offsets */ + +/* bus interface registers */ +#define PP_ChipID 0x0000 /* Chip identifier - must be 0x630E */ +#define PP_ChipRev 0x0002 /* Chip revision, model codes */ + +#define PP_IntReg 0x0022 /* Interrupt configuration */ +#define PP_IntReg_IRQ0 0x0000 /* Use INTR0 pin */ +#define PP_IntReg_IRQ1 0x0001 /* Use INTR1 pin */ +#define PP_IntReg_IRQ2 0x0002 /* Use INTR2 pin */ +#define PP_IntReg_IRQ3 0x0003 /* Use INTR3 pin */ + +/* status and control registers */ + +#define PP_RxCFG 0x0102 /* Receiver configuration */ +#define PP_RxCFG_Skip1 0x0040 /* Skip (i.e. discard) current frame */ +#define PP_RxCFG_Stream 0x0080 /* Enable streaming mode */ +#define PP_RxCFG_RxOK 0x0100 /* RxOK interrupt enable */ +#define PP_RxCFG_RxDMAonly 0x0200 /* Use RxDMA for all frames */ +#define PP_RxCFG_AutoRxDMA 0x0400 /* Select RxDMA automatically */ +#define PP_RxCFG_BufferCRC 0x0800 /* Include CRC characters in frame */ +#define PP_RxCFG_CRC 0x1000 /* Enable interrupt on CRC error */ +#define PP_RxCFG_RUNT 0x2000 /* Enable interrupt on RUNT frames */ +#define PP_RxCFG_EXTRA 0x4000 /* Enable interrupt on frames with extra data */ + +#define PP_RxCTL 0x0104 /* Receiver control */ +#define PP_RxCTL_IAHash 0x0040 /* Accept frames that match hash */ +#define PP_RxCTL_Promiscuous 0x0080 /* Accept any frame */ +#define PP_RxCTL_RxOK 0x0100 /* Accept well formed frames */ +#define PP_RxCTL_Multicast 0x0200 /* Accept multicast frames */ +#define PP_RxCTL_IA 0x0400 /* Accept frame that matches IA */ +#define PP_RxCTL_Broadcast 0x0800 /* Accept broadcast frames */ +#define PP_RxCTL_CRC 0x1000 /* Accept frames with bad CRC */ +#define PP_RxCTL_RUNT 0x2000 /* Accept runt frames */ +#define PP_RxCTL_EXTRA 0x4000 /* Accept frames that are too long */ + +#define PP_TxCFG 0x0106 /* Transmit configuration */ +#define PP_TxCFG_CRS 0x0040 /* Enable interrupt on loss of carrier */ +#define PP_TxCFG_SQE 0x0080 /* Enable interrupt on Signal Quality Error */ +#define PP_TxCFG_TxOK 0x0100 /* Enable interrupt on successful xmits */ +#define PP_TxCFG_Late 0x0200 /* Enable interrupt on "out of window" */ +#define PP_TxCFG_Jabber 0x0400 /* Enable interrupt on jabber detect */ +#define PP_TxCFG_Collision 0x0800 /* Enable interrupt if collision */ +#define PP_TxCFG_16Collisions 0x8000 /* Enable interrupt if > 16 collisions */ + +#define PP_TxCmd 0x0108 /* Transmit command status */ +#define PP_TxCmd_TxStart_5 0x0000 /* Start after 5 bytes in buffer */ +#define PP_TxCmd_TxStart_381 0x0040 /* Start after 381 bytes in buffer */ +#define PP_TxCmd_TxStart_1021 0x0080 /* Start after 1021 bytes in buffer */ +#define PP_TxCmd_TxStart_Full 0x00C0 /* Start after all bytes loaded */ +#define PP_TxCmd_Force 0x0100 /* Discard any pending packets */ +#define PP_TxCmd_OneCollision 0x0200 /* Abort after a single collision */ +#define PP_TxCmd_NoCRC 0x1000 /* Do not add CRC */ +#define PP_TxCmd_NoPad 0x2000 /* Do not pad short packets */ + +#define PP_BufCFG 0x010A /* Buffer configuration */ +#define PP_BufCFG_SWI 0x0040 /* Force interrupt via software */ +#define PP_BufCFG_RxDMA 0x0080 /* Enable interrupt on Rx DMA */ +#define PP_BufCFG_TxRDY 0x0100 /* Enable interrupt when ready for Tx */ +#define PP_BufCFG_TxUE 0x0200 /* Enable interrupt in Tx underrun */ +#define PP_BufCFG_RxMiss 0x0400 /* Enable interrupt on missed Rx packets */ +#define PP_BufCFG_Rx128 0x0800 /* Enable Rx interrupt after 128 bytes */ +#define PP_BufCFG_TxCol 0x1000 /* Enable int on Tx collision ctr overflow */ +#define PP_BufCFG_Miss 0x2000 /* Enable int on Rx miss ctr overflow */ +#define PP_BufCFG_RxDest 0x8000 /* Enable int on Rx dest addr match */ + +#define PP_LineCTL 0x0112 /* Line control */ +#define PP_LineCTL_Rx 0x0040 /* Enable receiver */ +#define PP_LineCTL_Tx 0x0080 /* Enable transmitter */ +#define PP_LineCTL_AUIonly 0x0100 /* AUI interface only */ +#define PP_LineCTL_AutoAUI10BT 0x0200 /* Autodetect AUI or 10BaseT interface */ +#define PP_LineCTL_ModBackoffE 0x0800 /* Enable modified backoff algorithm */ +#define PP_LineCTL_PolarityDis 0x1000 /* Disable Rx polarity autodetect */ +#define PP_LineCTL_2partDefDis 0x2000 /* Disable two-part defferal */ +#define PP_LineCTL_LoRxSquelch 0x4000 /* Reduce receiver squelch threshold */ + +#define PP_SelfCTL 0x0114 /* Chip self control */ +#define PP_SelfCTL_Reset 0x0040 /* Self-clearing reset */ +#define PP_SelfCTL_SWSuspend 0x0100 /* Initiate suspend mode */ +#define PP_SelfCTL_HWSleepE 0x0200 /* Enable SLEEP input */ +#define PP_SelfCTL_HWStandbyE 0x0400 /* Enable standby mode */ +#define PP_SelfCTL_HC0E 0x1000 /* use HCB0 for LINK LED */ +#define PP_SelfCTL_HC1E 0x2000 /* use HCB1 for BSTATUS LED */ +#define PP_SelfCTL_HCB0 0x4000 /* control LINK LED if HC0E set */ +#define PP_SelfCTL_HCB1 0x8000 /* control BSTATUS LED if HC1E set */ + +#define PP_BusCTL 0x0116 /* Bus control */ +#define PP_BusCTL_ResetRxDMA 0x0040 /* Reset RxDMA pointer */ +#define PP_BusCTL_DMAextend 0x0100 /* Extend DMA cycle */ +#define PP_BusCTL_UseSA 0x0200 /* Assert MEMCS16 on address decode */ +#define PP_BusCTL_MemoryE 0x0400 /* Enable memory mode */ +#define PP_BusCTL_DMAburst 0x0800 /* Limit DMA access burst */ +#define PP_BusCTL_IOCHRDYE 0x1000 /* Set IOCHRDY high impedence */ +#define PP_BusCTL_RxDMAsize 0x2000 /* Set DMA buffer size 64KB */ +#define PP_BusCTL_EnableIRQ 0x8000 /* Generate interrupt on interrupt event */ + +#define PP_TestCTL 0x0118 /* Test control */ +#define PP_TestCTL_DisableLT 0x0080 /* Disable link status */ +#define PP_TestCTL_ENDECloop 0x0200 /* Internal loopback */ +#define PP_TestCTL_AUIloop 0x0400 /* AUI loopback */ +#define PP_TestCTL_DisBackoff 0x0800 /* Disable backoff algorithm */ +#define PP_TestCTL_FDX 0x4000 /* Enable full duplex mode */ + +#define PP_ISQ 0x0120 /* Interrupt Status Queue */ + +#define PP_RER 0x0124 /* Receive event */ +#define PP_RER_IAHash 0x0040 /* Frame hash match */ +#define PP_RER_Dribble 0x0080 /* Frame had 1-7 extra bits after last byte */ +#define PP_RER_RxOK 0x0100 /* Frame received with no errors */ +#define PP_RER_Hashed 0x0200 /* Frame address hashed OK */ +#define PP_RER_IA 0x0400 /* Frame address matched IA */ +#define PP_RER_Broadcast 0x0800 /* Broadcast frame */ +#define PP_RER_CRC 0x1000 /* Frame had CRC error */ +#define PP_RER_RUNT 0x2000 /* Runt frame */ +#define PP_RER_EXTRA 0x4000 /* Frame was too long */ + +#define PP_TER 0x0128 /* Transmit event */ +#define PP_TER_CRS 0x0040 /* Carrier lost */ +#define PP_TER_SQE 0x0080 /* Signal Quality Error */ +#define PP_TER_TxOK 0x0100 /* Packet sent without error */ +#define PP_TER_Late 0x0200 /* Out of window */ +#define PP_TER_Jabber 0x0400 /* Stuck transmit? */ +#define PP_TER_NumCollisions 0x7800 /* Number of collisions */ +#define PP_TER_16Collisions 0x8000 /* > 16 collisions */ + +#define PP_BER 0x012C /* Buffer event */ +#define PP_BER_SWint 0x0040 /* Software interrupt */ +#define PP_BER_RxDMAFrame 0x0080 /* Received framed DMAed */ +#define PP_BER_Rdy4Tx 0x0100 /* Ready for transmission */ +#define PP_BER_TxUnderrun 0x0200 /* Transmit underrun */ +#define PP_BER_RxMiss 0x0400 /* Received frame missed */ +#define PP_BER_Rx128 0x0800 /* 128 bytes received */ +#define PP_BER_RxDest 0x8000 /* Received framed passed address filter */ + +#define PP_RxMiss 0x0130 /* Receiver miss counter */ + +#define PP_TxCol 0x0132 /* Transmit collision counter */ + +#define PP_LineSTAT 0x0134 /* Line status */ +#define PP_LineSTAT_LinkOK 0x0080 /* Line is connected and working */ +#define PP_LineSTAT_AUI 0x0100 /* Connected via AUI */ +#define PP_LineSTAT_10BT 0x0200 /* Connected via twisted pair */ +#define PP_LineSTAT_Polarity 0x1000 /* Line polarity OK (10BT only) */ +#define PP_LineSTAT_CRS 0x4000 /* Frame being received */ + +#define PP_SelfSTAT 0x0136 /* Chip self status */ +#define PP_SelfSTAT_33VActive 0x0040 /* supply voltage is 3.3V */ +#define PP_SelfSTAT_InitD 0x0080 /* Chip initialization complete */ +#define PP_SelfSTAT_SIBSY 0x0100 /* EEPROM is busy */ +#define PP_SelfSTAT_EEPROM 0x0200 /* EEPROM present */ +#define PP_SelfSTAT_EEPROM_OK 0x0400 /* EEPROM checks out */ +#define PP_SelfSTAT_ELPresent 0x0800 /* External address latch logic available */ +#define PP_SelfSTAT_EEsize 0x1000 /* Size of EEPROM */ + +#define PP_BusSTAT 0x0138 /* Bus status */ +#define PP_BusSTAT_TxBid 0x0080 /* Tx error */ +#define PP_BusSTAT_TxRDY 0x0100 /* Ready for Tx data */ + +#define PP_TDR 0x013C /* AUI Time Domain Reflectometer */ + +/* initiate transmit registers */ + +#define PP_TxCommand 0x0144 /* Tx Command */ +#define PP_TxLength 0x0146 /* Tx Length */ + + +/* address filter registers */ + +#define PP_LAF 0x0150 /* Logical address filter (6 bytes) */ +#define PP_IA 0x0158 /* Individual address (MAC) */ + +/* EEPROM Kram */ +#define SI_BUSY 0x0100 +#define PP_SelfST 0x0136 /* Self State register */ +#define PP_EECMD 0x0040 /* NVR Interface Command register */ +#define PP_EEData 0x0042 /* NVR Interface Data Register */ +#define EEPROM_WRITE_EN 0x00F0 +#define EEPROM_WRITE_DIS 0x0000 +#define EEPROM_WRITE_CMD 0x0100 +#define EEPROM_READ_CMD 0x0200 + + + +#endif /* CONFIG_DRIVER_CS8900 */ diff --git a/drivers/natsemi.c b/drivers/natsemi.c new file mode 100644 index 0000000..5a8c5b4 --- /dev/null +++ b/drivers/natsemi.c @@ -0,0 +1,881 @@ +/* + natsemi.c: A U-Boot driver for the NatSemi DP8381x series. + Author: Mark A. Rakes (mark_rakes@vivato.net) + + Adapted from an Etherboot driver written by: + + Copyright (C) 2001 Entity Cyber, Inc. + + This development of this Etherboot driver was funded by + + Sicom Systems: http://www.sicompos.com/ + + Author: Marty Connor (mdc@thinguin.org) + Adapted from a Linux driver which was written by Donald Becker + + This software may be used and distributed according to the terms + of the GNU Public License (GPL), incorporated herein by reference. + + Original Copyright Notice: + + Written/copyright 1999-2001 by Donald Becker. + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. License for under other terms may be + available. Contact the original author for details. + + The original author may be reached as becker@scyld.com, or at + Scyld Computing Corporation + 410 Severn Ave., Suite 210 + Annapolis MD 21403 + + Support information and updates available at + http://www.scyld.com/network/netsemi.html + + References: + http://www.scyld.com/expert/100mbps.html + http://www.scyld.com/expert/NWay.html + Datasheet is available from: + http://www.national.com/pf/DP/DP83815.html +*/ + +/* Revision History + * October 2002 mar 1.0 + * Initial U-Boot Release. Tested with Netgear FA311 board + * and dp83815 chipset on custom board +*/ + +/* Includes */ +#include <common.h> +#include <malloc.h> +#include <net.h> +#include <asm/io.h> +#include <pci.h> + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ + defined(CONFIG_NATSEMI) + +/* defines */ +#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/ + +#define DSIZE 0x00000FFF +#define ETH_ALEN 6 +#define CRC_SIZE 4 +#define TOUT_LOOP 500000 +#define TX_BUF_SIZE 1536 +#define RX_BUF_SIZE 1536 +#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */ + +/* Offsets to the device registers. + Unlike software-only systems, device drivers interact with complex hardware. + It's not useful to define symbolic names for every register bit in the + device. */ +enum register_offsets { + ChipCmd = 0x00, + ChipConfig = 0x04, + EECtrl = 0x08, + IntrMask = 0x14, + IntrEnable = 0x18, + TxRingPtr = 0x20, + TxConfig = 0x24, + RxRingPtr = 0x30, + RxConfig = 0x34, + ClkRun = 0x3C, + RxFilterAddr = 0x48, + RxFilterData = 0x4C, + SiliconRev = 0x58, + PCIPM = 0x44, + BasicControl = 0x80, + BasicStatus = 0x84, + /* These are from the spec, around page 78... on a separate table. */ + PGSEL = 0xCC, + PMDCSR = 0xE4, + TSTDAT = 0xFC, + DSPCFG = 0xF4, + SDCFG = 0x8C +}; + +/* Bit in ChipCmd. */ +enum ChipCmdBits { + ChipReset = 0x100, + RxReset = 0x20, + TxReset = 0x10, + RxOff = 0x08, + RxOn = 0x04, + TxOff = 0x02, + TxOn = 0x01 +}; + +enum ChipConfigBits { + LinkSts = 0x80000000, + HundSpeed = 0x40000000, + FullDuplex = 0x20000000, + TenPolarity = 0x10000000, + AnegDone = 0x08000000, + AnegEnBothBoth = 0x0000E000, + AnegDis100Full = 0x0000C000, + AnegEn100Both = 0x0000A000, + AnegDis100Half = 0x00008000, + AnegEnBothHalf = 0x00006000, + AnegDis10Full = 0x00004000, + AnegEn10Both = 0x00002000, + DuplexMask = 0x00008000, + SpeedMask = 0x00004000, + AnegMask = 0x00002000, + AnegDis10Half = 0x00000000, + ExtPhy = 0x00001000, + PhyRst = 0x00000400, + PhyDis = 0x00000200, + BootRomDisable = 0x00000004, + BEMode = 0x00000001, +}; + +enum TxConfig_bits { + TxDrthMask = 0x3f, + TxFlthMask = 0x3f00, + TxMxdmaMask = 0x700000, + TxMxdma_512 = 0x0, + TxMxdma_4 = 0x100000, + TxMxdma_8 = 0x200000, + TxMxdma_16 = 0x300000, + TxMxdma_32 = 0x400000, + TxMxdma_64 = 0x500000, + TxMxdma_128 = 0x600000, + TxMxdma_256 = 0x700000, + TxCollRetry = 0x800000, + TxAutoPad = 0x10000000, + TxMacLoop = 0x20000000, + TxHeartIgn = 0x40000000, + TxCarrierIgn = 0x80000000 +}; + +enum RxConfig_bits { + RxDrthMask = 0x3e, + RxMxdmaMask = 0x700000, + RxMxdma_512 = 0x0, + RxMxdma_4 = 0x100000, + RxMxdma_8 = 0x200000, + RxMxdma_16 = 0x300000, + RxMxdma_32 = 0x400000, + RxMxdma_64 = 0x500000, + RxMxdma_128 = 0x600000, + RxMxdma_256 = 0x700000, + RxAcceptLong = 0x8000000, + RxAcceptTx = 0x10000000, + RxAcceptRunt = 0x40000000, + RxAcceptErr = 0x80000000 +}; + +/* Bits in the RxMode register. */ +enum rx_mode_bits { + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0xC0000000, + AcceptMulticast = 0x00200000, + AcceptAllMulticast = 0x20000000, + AcceptAllPhys = 0x10000000, + AcceptMyPhys = 0x08000000 +}; + +typedef struct _BufferDesc { + u32 link; + vu_long cmdsts; + u32 bufptr; + u32 software_use; +} BufferDesc; + +/* Bits in network_desc.status */ +enum desc_status_bits { + DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000, + DescNoCRC = 0x10000000, DescPktOK = 0x08000000, + DescSizeMask = 0xfff, + + DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000, + DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000, + DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000, + DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000, + + DescRxAbort = 0x04000000, DescRxOver = 0x02000000, + DescRxDest = 0x01800000, DescRxLong = 0x00400000, + DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000, + DescRxCRC = 0x00080000, DescRxAlign = 0x00040000, + DescRxLoop = 0x00020000, DesRxColl = 0x00010000, +}; + +/* Globals */ +#ifdef NATSEMI_DEBUG +static int natsemi_debug = 0; /* 1 verbose debugging, 0 normal */ +#endif +static u32 SavedClkRun; +static unsigned int cur_rx; +static unsigned int advertising; +static unsigned int rx_config; +static unsigned int tx_config; + +/* Note: transmit and receive buffers and descriptors must be + longword aligned */ +static BufferDesc txd __attribute__ ((aligned(4))); +static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4))); + +static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4))); +static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] + __attribute__ ((aligned(4))); + +/* Function Prototypes */ +#if 0 +static void write_eeprom(struct eth_device *dev, long addr, int location, + short value); +#endif +static int read_eeprom(struct eth_device *dev, long addr, int location); +static int mdio_read(struct eth_device *dev, int phy_id, int location); +static int natsemi_init(struct eth_device *dev, bd_t * bis); +static void natsemi_reset(struct eth_device *dev); +static void natsemi_init_rxfilter(struct eth_device *dev); +static void natsemi_init_txd(struct eth_device *dev); +static void natsemi_init_rxd(struct eth_device *dev); +static void natsemi_set_rx_mode(struct eth_device *dev); +static void natsemi_check_duplex(struct eth_device *dev); +static int natsemi_send(struct eth_device *dev, volatile void *packet, + int length); +static int natsemi_poll(struct eth_device *dev); +static void natsemi_disable(struct eth_device *dev); + +static struct pci_device_id supported[] = { + {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815}, + {} +}; + +#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) +#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) + +static inline int +INW(struct eth_device *dev, u_long addr) +{ + return le16_to_cpu(*(vu_short *) (addr + dev->iobase)); +} + +static int +INL(struct eth_device *dev, u_long addr) +{ + return le32_to_cpu(*(vu_long *) (addr + dev->iobase)); +} + +static inline void +OUTW(struct eth_device *dev, int command, u_long addr) +{ + *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command); +} + +static inline void +OUTL(struct eth_device *dev, int command, u_long addr) +{ + *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command); +} + +/* + * Function: natsemi_initialize + * + * Description: Retrieves the MAC address of the card, and sets up some + * globals required by other routines, and initializes the NIC, making it + * ready to send and receive packets. + * + * Side effects: + * leaves the natsemi initialized, and ready to recieve packets. + * + * Returns: struct eth_device *: pointer to NIC data structure + */ + +int +natsemi_initialize(bd_t * bis) +{ + pci_dev_t devno; + int card_number = 0; + struct eth_device *dev; + u32 iobase, status, chip_config; + int i, idx = 0; + int prev_eedata; + u32 tmp; + + while (1) { + /* Find PCI device(s) */ + if ((devno = pci_find_devices(supported, idx++)) < 0) { + break; + } + + pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); + iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */ + + pci_write_config_dword(devno, PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + + /* Check if I/O accesses and Bus Mastering are enabled. */ + pci_read_config_dword(devno, PCI_COMMAND, &status); + if (!(status & PCI_COMMAND_MEMORY)) { + printf("Error: Can not enable MEM access.\n"); + continue; + } else if (!(status & PCI_COMMAND_MASTER)) { + printf("Error: Can not enable Bus Mastering.\n"); + continue; + } + + dev = (struct eth_device *) malloc(sizeof *dev); + + sprintf(dev->name, "dp83815#%d", card_number); + dev->iobase = bus_to_phys(iobase); +#ifdef NATSEMI_DEBUG + printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase); +#endif + dev->priv = (void *) devno; + dev->init = natsemi_init; + dev->halt = natsemi_disable; + dev->send = natsemi_send; + dev->recv = natsemi_poll; + + eth_register(dev); + + card_number++; + + /* Set the latency timer for value. */ + pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); + + udelay(10 * 1000); + + /* natsemi has a non-standard PM control register + * in PCI config space. Some boards apparently need + * to be brought to D0 in this manner. */ + pci_read_config_dword(devno, PCIPM, &tmp); + if (tmp & (0x03 | 0x100)) { + /* D0 state, disable PME assertion */ + u32 newtmp = tmp & ~(0x03 | 0x100); + pci_write_config_dword(devno, PCIPM, newtmp); + } + + printf("natsemi: EEPROM contents:\n"); + for (i = 0; i <= EEPROM_SIZE; i++) { + short eedata = read_eeprom(dev, EECtrl, i); + printf(" %04hx", eedata); + } + printf("\n"); + + /* get MAC address */ + prev_eedata = read_eeprom(dev, EECtrl, 6); + for (i = 0; i < 3; i++) { + int eedata = read_eeprom(dev, EECtrl, i + 7); + dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15); + dev->enetaddr[i*2+1] = eedata >> 7; + prev_eedata = eedata; + } + + /* Reset the chip to erase any previous misconfiguration. */ + OUTL(dev, ChipReset, ChipCmd); + + advertising = mdio_read(dev, 1, 4); + chip_config = INL(dev, ChipConfig); +#ifdef NATSEMI_DEBUG + printf("%s: Transceiver status %#08X advertising %#08X\n", + dev->name, (int) INL(dev, BasicStatus), advertising); + printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n", + dev->name, chip_config & AnegMask ? "enabled, advertise" : + "disabled, force", chip_config & SpeedMask ? "0" : "", + chip_config & DuplexMask ? "full" : "half"); +#endif + chip_config |= AnegEnBothBoth; +#ifdef NATSEMI_DEBUG + printf("%s: changed to autoneg. %s 10%s %s duplex.\n", + dev->name, chip_config & AnegMask ? "enabled, advertise" : + "disabled, force", chip_config & SpeedMask ? "0" : "", + chip_config & DuplexMask ? "full" : "half"); +#endif + /*write new autoneg bits, reset phy*/ + OUTL(dev, (chip_config | PhyRst), ChipConfig); + /*un-reset phy*/ + OUTL(dev, chip_config, ChipConfig); + + /* Disable PME: + * The PME bit is initialized from the EEPROM contents. + * PCI cards probably have PME disabled, but motherboard + * implementations may have PME set to enable WakeOnLan. + * With PME set the chip will scan incoming packets but + * nothing will be written to memory. */ + SavedClkRun = INL(dev, ClkRun); + OUTL(dev, SavedClkRun & ~0x100, ClkRun); + } + return card_number; +} + +/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. + The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses. */ + +/* Delay between EEPROM clock transitions. + No extra delay is needed with 33Mhz PCI, but future 66Mhz + access may need a delay. */ +#define eeprom_delay(ee_addr) INL(dev, ee_addr) + +enum EEPROM_Ctrl_Bits { + EE_ShiftClk = 0x04, + EE_DataIn = 0x01, + EE_ChipSelect = 0x08, + EE_DataOut = 0x02 +}; + +#define EE_Write0 (EE_ChipSelect) +#define EE_Write1 (EE_ChipSelect | EE_DataIn) +/* The EEPROM commands include the alway-set leading bit. */ +enum EEPROM_Cmds { + EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6), + EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6), +}; + +#if 0 +static void +write_eeprom(struct eth_device *dev, long addr, int location, short value) +{ + int i; + int ee_addr = (typeof(ee_addr))addr; + short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/ + short write_cmd = location | EE_WriteCmd; + +#ifdef NATSEMI_DEBUG + printf("write_eeprom: %08x, %04hx, %04hx\n", + dev->iobase + ee_addr, write_cmd, value); +#endif + /* Shift the write enable command bits out. */ + for (i = 9; i >= 0; i--) { + short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0; + OUTL(dev, cmdval, ee_addr); + eeprom_delay(ee_addr); + OUTL(dev, cmdval | EE_ShiftClk, ee_addr); + eeprom_delay(ee_addr); + } + + OUTL(dev, 0, ee_addr); /*bring chip select low*/ + OUTL(dev, EE_ShiftClk, ee_addr); + eeprom_delay(ee_addr); + + /* Shift the write command bits out. */ + for (i = 9; i >= 0; i--) { + short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0; + OUTL(dev, cmdval, ee_addr); + eeprom_delay(ee_addr); + OUTL(dev, cmdval | EE_ShiftClk, ee_addr); + eeprom_delay(ee_addr); + } + + for (i = 0; i < 16; i++) { + short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0; + OUTL(dev, cmdval, ee_addr); + eeprom_delay(ee_addr); + OUTL(dev, cmdval | EE_ShiftClk, ee_addr); + eeprom_delay(ee_addr); + } + + OUTL(dev, 0, ee_addr); /*bring chip select low*/ + OUTL(dev, EE_ShiftClk, ee_addr); + for (i = 0; i < 200000; i++) { + OUTL(dev, EE_Write0, ee_addr); /*poll for done*/ + if (INL(dev, ee_addr) & EE_DataOut) { + break; /*finished*/ + } + } + eeprom_delay(ee_addr); + + /* Terminate the EEPROM access. */ + OUTL(dev, EE_Write0, ee_addr); + OUTL(dev, 0, ee_addr); + return; +} +#endif + +static int +read_eeprom(struct eth_device *dev, long addr, int location) +{ + int i; + int retval = 0; + int ee_addr = (typeof(ee_addr))addr; + int read_cmd = location | EE_ReadCmd; + + OUTL(dev, EE_Write0, ee_addr); + + /* Shift the read command bits out. */ + for (i = 10; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0; + OUTL(dev, dataval, ee_addr); + eeprom_delay(ee_addr); + OUTL(dev, dataval | EE_ShiftClk, ee_addr); + eeprom_delay(ee_addr); + } + OUTL(dev, EE_ChipSelect, ee_addr); + eeprom_delay(ee_addr); + + for (i = 0; i < 16; i++) { + OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr); + eeprom_delay(ee_addr); + retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0; + OUTL(dev, EE_ChipSelect, ee_addr); + eeprom_delay(ee_addr); + } + + /* Terminate the EEPROM access. */ + OUTL(dev, EE_Write0, ee_addr); + OUTL(dev, 0, ee_addr); +#ifdef NATSEMI_DEBUG + if (natsemi_debug) + printf("read_eeprom: %08x, %08x, retval %08x\n", + dev->iobase + ee_addr, read_cmd, retval); +#endif + return retval; +} + +/* MII transceiver control section. + The 83815 series has an internal transceiver, and we present the + management registers as if they were MII connected. */ + +static int +mdio_read(struct eth_device *dev, int phy_id, int location) +{ + if (phy_id == 1 && location < 32) + return INL(dev, BasicControl+(location<<2))&0xffff; + else + return 0xffff; +} + +/* Function: natsemi_init + * + * Description: resets the ethernet controller chip and configures + * registers and data structures required for sending and receiving packets. + * + * Arguments: struct eth_device *dev: NIC data structure + * + * returns: int. + */ + +static int +natsemi_init(struct eth_device *dev, bd_t * bis) +{ + + natsemi_reset(dev); + + /* Disable PME: + * The PME bit is initialized from the EEPROM contents. + * PCI cards probably have PME disabled, but motherboard + * implementations may have PME set to enable WakeOnLan. + * With PME set the chip will scan incoming packets but + * nothing will be written to memory. */ + OUTL(dev, SavedClkRun & ~0x100, ClkRun); + + natsemi_init_rxfilter(dev); + natsemi_init_txd(dev); + natsemi_init_rxd(dev); + + /* Configure the PCI bus bursts and FIFO thresholds. */ + tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002); + rx_config = RxMxdma_256 | 0x20; + +#ifdef NATSEMI_DEBUG + printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config); + printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config); +#endif + OUTL(dev, tx_config, TxConfig); + OUTL(dev, rx_config, RxConfig); + + natsemi_check_duplex(dev); + natsemi_set_rx_mode(dev); + + OUTL(dev, (RxOn | TxOn), ChipCmd); + return 1; +} + +/* + * Function: natsemi_reset + * + * Description: soft resets the controller chip + * + * Arguments: struct eth_device *dev: NIC data structure + * + * Returns: void. + */ +static void +natsemi_reset(struct eth_device *dev) +{ + OUTL(dev, ChipReset, ChipCmd); + + /* On page 78 of the spec, they recommend some settings for "optimum + performance" to be done in sequence. These settings optimize some + of the 100Mbit autodetection circuitry. Also, we only want to do + this for rev C of the chip. */ + if (INL(dev, SiliconRev) == 0x302) { + OUTW(dev, 0x0001, PGSEL); + OUTW(dev, 0x189C, PMDCSR); + OUTW(dev, 0x0000, TSTDAT); + OUTW(dev, 0x5040, DSPCFG); + OUTW(dev, 0x008C, SDCFG); + } + /* Disable interrupts using the mask. */ + OUTL(dev, 0, IntrMask); + OUTL(dev, 0, IntrEnable); +} + +/* Function: natsemi_init_rxfilter + * + * Description: sets receive filter address to our MAC address + * + * Arguments: struct eth_device *dev: NIC data structure + * + * returns: void. + */ + +static void +natsemi_init_rxfilter(struct eth_device *dev) +{ + int i; + + for (i = 0; i < ETH_ALEN; i += 2) { + OUTL(dev, i, RxFilterAddr); + OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8), + RxFilterData); + } +} + +/* + * Function: natsemi_init_txd + * + * Description: initializes the Tx descriptor + * + * Arguments: struct eth_device *dev: NIC data structure + * + * returns: void. + */ + +static void +natsemi_init_txd(struct eth_device *dev) +{ + txd.link = (u32) 0; + txd.cmdsts = (u32) 0; + txd.bufptr = (u32) & txb[0]; + + /* load Transmit Descriptor Register */ + OUTL(dev, (u32) & txd, TxRingPtr); +#ifdef NATSEMI_DEBUG + printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n", + INL(dev, TxRingPtr)); +#endif +} + +/* Function: natsemi_init_rxd + * + * Description: initializes the Rx descriptor ring + * + * Arguments: struct eth_device *dev: NIC data structure + * + * Returns: void. + */ + +static void +natsemi_init_rxd(struct eth_device *dev) +{ + int i; + + cur_rx = 0; + + /* init RX descriptor */ + for (i = 0; i < NUM_RX_DESC; i++) { + rxd[i].link = + cpu_to_le32((i + 1 < + NUM_RX_DESC) ? (u32) & rxd[i + + 1] : (u32) & + rxd[0]); + rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE); + rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]); +#ifdef NATSEMI_DEBUG + printf + ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n", + i, &rxd[i], le32_to_cpu(rxd[i].link), + rxd[i].cmdsts, rxd[i].bufptr); +#endif + } + + /* load Receive Descriptor Register */ + OUTL(dev, (u32) & rxd[0], RxRingPtr); + +#ifdef NATSEMI_DEBUG + printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n", + INL(dev, RxRingPtr)); +#endif +} + +/* Function: natsemi_set_rx_mode + * + * Description: + * sets the receive mode to accept all broadcast packets and packets + * with our MAC address, and reject all multicast packets. + * + * Arguments: struct eth_device *dev: NIC data structure + * + * Returns: void. + */ + +static void +natsemi_set_rx_mode(struct eth_device *dev) +{ + u32 rx_mode = AcceptBroadcast | AcceptMyPhys; + + OUTL(dev, rx_mode, RxFilterAddr); +} + +static void +natsemi_check_duplex(struct eth_device *dev) +{ + int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0; + +#ifdef NATSEMI_DEBUG + printf("%s: Setting %s-duplex based on negotiated link" + " capability.\n", dev->name, duplex ? "full" : "half"); +#endif + if (duplex) { + rx_config |= RxAcceptTx; + tx_config |= (TxCarrierIgn | TxHeartIgn); + } else { + rx_config &= ~RxAcceptTx; + tx_config &= ~(TxCarrierIgn | TxHeartIgn); + } + OUTL(dev, tx_config, TxConfig); + OUTL(dev, rx_config, RxConfig); +} + +/* Function: natsemi_send + * + * Description: transmits a packet and waits for completion or timeout. + * + * Returns: void. */ +static int +natsemi_send(struct eth_device *dev, volatile void *packet, int length) +{ + u32 i, status = 0; + u32 tx_status = 0; + + /* Stop the transmitter */ + OUTL(dev, TxOff, ChipCmd); + +#ifdef NATSEMI_DEBUG + if (natsemi_debug) + printf("natsemi_send: sending %d bytes\n", (int) length); +#endif + + /* set the transmit buffer descriptor and enable Transmit State Machine */ + txd.link = cpu_to_le32(0); + txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet)); + txd.cmdsts = cpu_to_le32(DescOwn | length); + + /* load Transmit Descriptor Register */ + OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr); +#ifdef NATSEMI_DEBUG + if (natsemi_debug) + printf("natsemi_send: TX descriptor register loaded with: %#08X\n", + INL(dev, TxRingPtr)); +#endif + /* restart the transmitter */ + OUTL(dev, TxOn, ChipCmd); + + for (i = 0; + ((vu_long)tx_status = le32_to_cpu(txd.cmdsts)) & DescOwn; + i++) { + if (i >= TOUT_LOOP) { + printf + ("%s: tx error buffer not ready: txd.cmdsts == %#X\n", + dev->name, tx_status); + goto Done; + } + } + + if (!(tx_status & DescPktOK)) { + printf("natsemi_send: Transmit error, Tx status %X.\n", + tx_status); + goto Done; + } + + status = 1; + Done: + return status; +} + +/* Function: natsemi_poll + * + * Description: checks for a received packet and returns it if found. + * + * Arguments: struct eth_device *dev: NIC data structure + * + * Returns: 1 if packet was received. + * 0 if no packet was received. + * + * Side effects: + * Returns (copies) the packet to the array dev->packet. + * Returns the length of the packet. + */ + +static int +natsemi_poll(struct eth_device *dev) +{ + int retstat = 0; + int length = 0; + u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts); + + if (!(rx_status & (u32) DescOwn)) + return retstat; +#ifdef NATSEMI_DEBUG + if (natsemi_debug) + printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n", + cur_rx, rx_status); +#endif + length = (rx_status & DSIZE) - CRC_SIZE; + + if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) { + printf + ("natsemi_poll: Corrupted packet received, buffer status = %X\n", + rx_status); + retstat = 0; + } else { /* give packet to higher level routine */ + NetReceive((rxb + cur_rx * RX_BUF_SIZE), length); + retstat = 1; + } + + /* return the descriptor and buffer to receive ring */ + rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE); + rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]); + + if (++cur_rx == NUM_RX_DESC) + cur_rx = 0; + + /* re-enable the potentially idle receive state machine */ + OUTL(dev, RxOn, ChipCmd); + + return retstat; +} + +/* Function: natsemi_disable + * + * Description: Turns off interrupts and stops Tx and Rx engines + * + * Arguments: struct eth_device *dev: NIC data structure + * + * Returns: void. + */ + +static void +natsemi_disable(struct eth_device *dev) +{ + /* Disable interrupts using the mask. */ + OUTL(dev, 0, IntrMask); + OUTL(dev, 0, IntrEnable); + + /* Stop the chip's Tx and Rx processes. */ + OUTL(dev, RxOff | TxOff, ChipCmd); + + /* Restore PME enable bit */ + OUTL(dev, SavedClkRun, ClkRun); +} + +#endif diff --git a/drivers/nicext.h b/drivers/nicext.h new file mode 100644 index 0000000..0879dc2 --- /dev/null +++ b/drivers/nicext.h @@ -0,0 +1,110 @@ +/**************************************************************************** + * Copyright(c) 2000-2001 Broadcom Corporation. All rights reserved. + * + * 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. + * + * Name: nicext.h + * + * Description: Broadcom Network Interface Card Extension (NICE) is an + * extension to Linux NET device kernel mode drivers. + * NICE is designed to provide additional functionalities, + * such as receive packet intercept. To support Broadcom NICE, + * the network device driver can be modified by adding an + * device ioctl handler and by indicating receiving packets + * to the NICE receive handler. Broadcom NICE will only be + * enabled by a NICE-aware intermediate driver, such as + * Broadcom Advanced Server Program Driver (BASP). When NICE + * is not enabled, the modified network device drivers + * functions exactly as other non-NICE aware drivers. + * + * Author: Frankie Fan + * + * Created: September 17, 2000 + * + ****************************************************************************/ +#ifndef _nicext_h_ +#define _nicext_h_ + +/* + * ioctl for NICE + */ +#define SIOCNICE SIOCDEVPRIVATE+7 + +/* + * SIOCNICE: + * + * The following structure needs to be less than IFNAMSIZ (16 bytes) because + * we're overloading ifreq.ifr_ifru. + * + * If 16 bytes is not enough, we should consider relaxing this because + * this is no field after ifr_ifru in the ifreq structure. But we may + * run into future compatiability problem in case of changing struct ifreq. + */ +struct nice_req +{ + __u32 cmd; + + union + { +#ifdef __KERNEL__ + /* cmd = NICE_CMD_SET_RX or NICE_CMD_GET_RX */ + struct + { + void (*nrqus1_rx)( struct sk_buff*, void* ); + void* nrqus1_ctx; + } nrqu_nrqus1; + + /* cmd = NICE_CMD_QUERY_SUPPORT */ + struct + { + __u32 nrqus2_magic; + __u32 nrqus2_support_rx:1; + __u32 nrqus2_support_vlan:1; + __u32 nrqus2_support_get_speed:1; + } nrqu_nrqus2; +#endif + + /* cmd = NICE_CMD_GET_SPEED */ + struct + { + unsigned int nrqus3_speed; /* 0 if link is down, */ + /* otherwise speed in Mbps */ + } nrqu_nrqus3; + + /* cmd = NICE_CMD_BLINK_LED */ + struct + { + unsigned int nrqus4_blink_time; /* blink duration in seconds */ + } nrqu_nrqus4; + + } nrq_nrqu; +}; + +#define nrq_rx nrq_nrqu.nrqu_nrqus1.nrqus1_rx +#define nrq_ctx nrq_nrqu.nrqu_nrqus1.nrqus1_ctx +#define nrq_support_rx nrq_nrqu.nrqu_nrqus2.nrqus2_support_rx +#define nrq_magic nrq_nrqu.nrqu_nrqus2.nrqus2_magic +#define nrq_support_vlan nrq_nrqu.nrqu_nrqus2.nrqus2_support_vlan +#define nrq_support_get_speed nrq_nrqu.nrqu_nrqus2.nrqus2_support_get_speed +#define nrq_speed nrq_nrqu.nrqu_nrqus3.nrqus3_speed +#define nrq_blink_time nrq_nrqu.nrqu_nrqus4.nrqus4_blink_time + +/* + * magic constants + */ +#define NICE_REQUESTOR_MAGIC 0x4543494E /* NICE in ascii */ +#define NICE_DEVICE_MAGIC 0x4E494345 /* ECIN in ascii */ + +/* + * command field + */ +#define NICE_CMD_QUERY_SUPPORT 0x00000001 +#define NICE_CMD_SET_RX 0x00000002 +#define NICE_CMD_GET_RX 0x00000003 +#define NICE_CMD_GET_SPEED 0x00000004 +#define NICE_CMD_BLINK_LED 0x00000005 + +#endif /* _nicext_h_ */ + diff --git a/drivers/ns8382x.c b/drivers/ns8382x.c new file mode 100644 index 0000000..978080e --- /dev/null +++ b/drivers/ns8382x.c @@ -0,0 +1,863 @@ +/* + ns8382x.c: A U-Boot driver for the NatSemi DP8382[01]. + ported by: Mark A. Rakes (mark_rakes@vivato.net) + + Adapted from: + 1. an Etherboot driver for DP8381[56] written by: + Copyright (C) 2001 Entity Cyber, Inc. + + This development of this Etherboot driver was funded by + Sicom Systems: http://www.sicompos.com/ + + Author: Marty Connor (mdc@thinguin.org) + Adapted from a Linux driver which was written by Donald Becker + + This software may be used and distributed according to the terms + of the GNU Public License (GPL), incorporated herein by reference. + + 2. A Linux driver by Donald Becker, ns820.c: + Written/copyright 1999-2002 by Donald Becker. + + This software may be used and distributed according to the terms of + the GNU General Public License (GPL), incorporated herein by reference. + Drivers based on or derived from this code fall under the GPL and must + retain the authorship, copyright and license notice. This file is not + a complete program and may only be used when the entire operating + system is licensed under the GPL. License for under other terms may be + available. Contact the original author for details. + + The original author may be reached as becker@scyld.com, or at + Scyld Computing Corporation + 410 Severn Ave., Suite 210 + Annapolis MD 21403 + + Support information and updates available at + http://www.scyld.com/network/netsemi.html + + Datasheets available from: + http://www.national.com/pf/DP/DP83820.html + http://www.national.com/pf/DP/DP83821.html +*/ + +/* Revision History + * October 2002 mar 1.0 + * Initial U-Boot Release. + * Tested with Netgear GA622T (83820) + * and SMC9452TX (83821) + * NOTE: custom boards with these chips may (likely) require + * a programmed EEPROM device (if present) in order to work + * correctly. +*/ + +/* Includes */ +#include <common.h> +#include <malloc.h> +#include <net.h> +#include <asm/io.h> +#include <pci.h> + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ + defined(CONFIG_NS8382X) + +/* defines */ +#define DSIZE 0x00000FFF +#define ETH_ALEN 6 +#define CRC_SIZE 4 +#define TOUT_LOOP 500000 +#define TX_BUF_SIZE 1536 +#define RX_BUF_SIZE 1536 +#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */ + +enum register_offsets { + ChipCmd = 0x00, + ChipConfig = 0x04, + EECtrl = 0x08, + IntrMask = 0x14, + IntrEnable = 0x18, + TxRingPtr = 0x20, + TxRingPtrHi = 0x24, + TxConfig = 0x28, + RxRingPtr = 0x30, + RxRingPtrHi = 0x34, + RxConfig = 0x38, + PriQueue = 0x3C, + RxFilterAddr = 0x48, + RxFilterData = 0x4C, + ClkRun = 0xCC, + PCIPM = 0x44, +}; + +enum ChipCmdBits { + ChipReset = 0x100, + RxReset = 0x20, + TxReset = 0x10, + RxOff = 0x08, + RxOn = 0x04, + TxOff = 0x02, + TxOn = 0x01 +}; + +enum ChipConfigBits { + LinkSts = 0x80000000, + GigSpeed = 0x40000000, + HundSpeed = 0x20000000, + FullDuplex = 0x10000000, + TBIEn = 0x01000000, + Mode1000 = 0x00400000, + T64En = 0x00004000, + D64En = 0x00001000, + M64En = 0x00000800, + PhyRst = 0x00000400, + PhyDis = 0x00000200, + ExtStEn = 0x00000100, + BEMode = 0x00000001, +}; +#define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex) + +enum TxConfig_bits { + TxDrthMask = 0x000000ff, + TxFlthMask = 0x0000ff00, + TxMxdmaMask = 0x00700000, + TxMxdma_8 = 0x00100000, + TxMxdma_16 = 0x00200000, + TxMxdma_32 = 0x00300000, + TxMxdma_64 = 0x00400000, + TxMxdma_128 = 0x00500000, + TxMxdma_256 = 0x00600000, + TxMxdma_512 = 0x00700000, + TxMxdma_1024 = 0x00000000, + TxCollRetry = 0x00800000, + TxAutoPad = 0x10000000, + TxMacLoop = 0x20000000, + TxHeartIgn = 0x40000000, + TxCarrierIgn = 0x80000000 +}; + +enum RxConfig_bits { + RxDrthMask = 0x0000003e, + RxMxdmaMask = 0x00700000, + RxMxdma_8 = 0x00100000, + RxMxdma_16 = 0x00200000, + RxMxdma_32 = 0x00300000, + RxMxdma_64 = 0x00400000, + RxMxdma_128 = 0x00500000, + RxMxdma_256 = 0x00600000, + RxMxdma_512 = 0x00700000, + RxMxdma_1024 = 0x00000000, + RxAcceptLenErr = 0x04000000, + RxAcceptLong = 0x08000000, + RxAcceptTx = 0x10000000, + RxStripCRC = 0x20000000, + RxAcceptRunt = 0x40000000, + RxAcceptErr = 0x80000000, +}; + +/* Bits in the RxMode register. */ +enum rx_mode_bits { + RxFilterEnable = 0x80000000, + AcceptAllBroadcast = 0x40000000, + AcceptAllMulticast = 0x20000000, + AcceptAllUnicast = 0x10000000, + AcceptPerfectMatch = 0x08000000, +}; + +typedef struct _BufferDesc { + u32 link; + u32 bufptr; + vu_long cmdsts; + u32 extsts; /*not used here */ +} BufferDesc; + +/* Bits in network_desc.status */ +enum desc_status_bits { + DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000, + DescNoCRC = 0x10000000, DescPktOK = 0x08000000, + DescSizeMask = 0xfff, + + DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000, + DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000, + DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000, + DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000, + + DescRxAbort = 0x04000000, DescRxOver = 0x02000000, + DescRxDest = 0x01800000, DescRxLong = 0x00400000, + DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000, + DescRxCRC = 0x00080000, DescRxAlign = 0x00040000, + DescRxLoop = 0x00020000, DesRxColl = 0x00010000, +}; + +/* Bits in MEAR */ +enum mii_reg_bits { + MDIO_ShiftClk = 0x0040, + MDIO_EnbOutput = 0x0020, + MDIO_Data = 0x0010, +}; + +/* PHY Register offsets. */ +enum phy_reg_offsets { + BMCR = 0x00, + BMSR = 0x01, + PHYIDR1 = 0x02, + PHYIDR2 = 0x03, + ANAR = 0x04, + KTCR = 0x09, +}; + +/* basic mode control register bits */ +enum bmcr_bits { + Bmcr_Reset = 0x8000, + Bmcr_Loop = 0x4000, + Bmcr_Speed0 = 0x2000, + Bmcr_AutoNegEn = 0x1000, /*if set ignores Duplex, Speed[01] */ + Bmcr_RstAutoNeg = 0x0200, + Bmcr_Duplex = 0x0100, + Bmcr_Speed1 = 0x0040, + Bmcr_Force10H = 0x0000, + Bmcr_Force10F = 0x0100, + Bmcr_Force100H = 0x2000, + Bmcr_Force100F = 0x2100, + Bmcr_Force1000H = 0x0040, + Bmcr_Force1000F = 0x0140, +}; + +/* auto negotiation advertisement register */ +enum anar_bits { + anar_adv_100F = 0x0100, + anar_adv_100H = 0x0080, + anar_adv_10F = 0x0040, + anar_adv_10H = 0x0020, + anar_ieee_8023 = 0x0001, +}; + +/* 1K-base T control register */ +enum ktcr_bits { + ktcr_adv_1000H = 0x0100, + ktcr_adv_1000F = 0x0200, +}; + +/* Globals */ +static u32 SavedClkRun; +static unsigned int cur_rx; +static unsigned int rx_config; +static unsigned int tx_config; + +/* Note: transmit and receive buffers and descriptors must be + long long word aligned */ +static BufferDesc txd __attribute__ ((aligned(8))); +static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8))); +static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8))); +static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] + __attribute__ ((aligned(8))); + +/* Function Prototypes */ +static int mdio_read(struct eth_device *dev, int phy_id, int addr); +static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value); +static void mdio_sync(struct eth_device *dev, u32 offset); +static int ns8382x_init(struct eth_device *dev, bd_t * bis); +static void ns8382x_reset(struct eth_device *dev); +static void ns8382x_init_rxfilter(struct eth_device *dev); +static void ns8382x_init_txd(struct eth_device *dev); +static void ns8382x_init_rxd(struct eth_device *dev); +static void ns8382x_set_rx_mode(struct eth_device *dev); +static void ns8382x_check_duplex(struct eth_device *dev); +static int ns8382x_send(struct eth_device *dev, volatile void *packet, + int length); +static int ns8382x_poll(struct eth_device *dev); +static void ns8382x_disable(struct eth_device *dev); + +static struct pci_device_id supported[] = { + {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_8382x}, + {} +}; + +#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) +#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) + +static inline int +INW(struct eth_device *dev, u_long addr) +{ + return le16_to_cpu(*(vu_short *) (addr + dev->iobase)); +} + +static int +INL(struct eth_device *dev, u_long addr) +{ + return le32_to_cpu(*(vu_long *) (addr + dev->iobase)); +} + +static inline void +OUTW(struct eth_device *dev, int command, u_long addr) +{ + *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command); +} + +static inline void +OUTL(struct eth_device *dev, int command, u_long addr) +{ + *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command); +} + +/* Function: ns8382x_initialize + * Description: Retrieves the MAC address of the card, and sets up some + * globals required by other routines, and initializes the NIC, making it + * ready to send and receive packets. + * Side effects: initializes ns8382xs, ready to recieve packets. + * Returns: int: number of cards found + */ + +int +ns8382x_initialize(bd_t * bis) +{ + pci_dev_t devno; + int card_number = 0; + struct eth_device *dev; + u32 iobase, status; + int i, idx = 0; + u32 phyAddress; + u32 tmp; + u32 chip_config; + + while (1) { /* Find PCI device(s) */ + if ((devno = pci_find_devices(supported, idx++)) < 0) + break; + + pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); + iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */ + +#ifdef NS8382X_DEBUG + printf("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase); +#endif + + pci_write_config_dword(devno, PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + + /* Check if I/O accesses and Bus Mastering are enabled. */ + pci_read_config_dword(devno, PCI_COMMAND, &status); + if (!(status & PCI_COMMAND_MEMORY)) { + printf("Error: Can not enable MEM access.\n"); + continue; + } else if (!(status & PCI_COMMAND_MASTER)) { + printf("Error: Can not enable Bus Mastering.\n"); + continue; + } + + dev = (struct eth_device *) malloc(sizeof *dev); + + sprintf(dev->name, "dp8382x#%d", card_number); + dev->iobase = bus_to_phys(iobase); + dev->priv = (void *) devno; + dev->init = ns8382x_init; + dev->halt = ns8382x_disable; + dev->send = ns8382x_send; + dev->recv = ns8382x_poll; + + /* ns8382x has a non-standard PM control register + * in PCI config space. Some boards apparently need + * to be brought to D0 in this manner. */ + pci_read_config_dword(devno, PCIPM, &tmp); + if (tmp & (0x03 | 0x100)) { /* D0 state, disable PME assertion */ + u32 newtmp = tmp & ~(0x03 | 0x100); + pci_write_config_dword(devno, PCIPM, newtmp); + } + + /* get MAC address */ + for (i = 0; i < 3; i++) { + u32 data; + char *mac = &dev->enetaddr[i * 2]; + + OUTL(dev, i * 2, RxFilterAddr); + data = INL(dev, RxFilterData); + *mac++ = data; + *mac++ = data >> 8; + } + /* get PHY address, can't be zero */ + for (phyAddress = 1; phyAddress < 32; phyAddress++) { + u32 rev, phy1; + + phy1 = mdio_read(dev, phyAddress, PHYIDR1); + if (phy1 == 0x2000) { /*check for 83861/91 */ + rev = mdio_read(dev, phyAddress, PHYIDR2); + if ((rev & ~(0x000f)) == 0x00005c50 || + (rev & ~(0x000f)) == 0x00005c60) { +#ifdef NS8382X_DEBUG + printf("phy rev is %x\n", rev); + printf("phy address is %x\n", + phyAddress); +#endif + break; + } + } + } + + /* set phy to autonegotiate && advertise everything */ + mdio_write(dev, phyAddress, KTCR, + (ktcr_adv_1000H | ktcr_adv_1000F)); + mdio_write(dev, phyAddress, ANAR, + (anar_adv_100F | anar_adv_100H | anar_adv_10H | + anar_adv_10F | anar_ieee_8023)); + mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */ + mdio_write(dev, phyAddress, BMCR, + (Bmcr_AutoNegEn | Bmcr_RstAutoNeg)); + /* Reset the chip to erase any previous misconfiguration. */ + OUTL(dev, (ChipReset), ChipCmd); + + chip_config = INL(dev, ChipConfig); + /* reset the phy */ + OUTL(dev, (chip_config | PhyRst), ChipConfig); + /* power up and initialize transceiver */ + OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig); + + mdio_sync(dev, EECtrl); +#ifdef NS8382X_DEBUG + { + u32 chpcfg = + INL(dev, ChipConfig) ^ SpeedStatus_Polarity; + + printf("%s: Transceiver 10%s %s duplex.\n", dev->name, + (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed) + ? "0" : "", + chpcfg & FullDuplex ? "full" : "half"); + printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, + dev->enetaddr[0], dev->enetaddr[1], + dev->enetaddr[2], dev->enetaddr[3], + dev->enetaddr[4], dev->enetaddr[5]); + } +#endif + /* Disable PME: + * The PME bit is initialized from the EEPROM contents. + * PCI cards probably have PME disabled, but motherboard + * implementations may have PME set to enable WakeOnLan. + * With PME set the chip will scan incoming packets but + * nothing will be written to memory. */ + SavedClkRun = INL(dev, ClkRun); + OUTL(dev, SavedClkRun & ~0x100, ClkRun); + + eth_register(dev); + + card_number++; + + pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60); + + udelay(10 * 1000); + } + return card_number; +} + +/* MII transceiver control section. + Read and write MII registers using software-generated serial MDIO + protocol. See the MII specifications or DP83840A data sheet for details. + + The maximum data clock rate is 2.5 Mhz. To meet minimum timing we + must flush writes to the PCI bus with a PCI read. */ +#define mdio_delay(mdio_addr) INL(dev, mdio_addr) + +#define MDIO_EnbIn (0) +#define MDIO_WRITE0 (MDIO_EnbOutput) +#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput) + +/* Generate the preamble required for initial synchronization and + a few older transceivers. */ +static void +mdio_sync(struct eth_device *dev, u32 offset) +{ + int bits = 32; + + /* Establish sync by sending at least 32 logic ones. */ + while (--bits >= 0) { + OUTL(dev, MDIO_WRITE1, offset); + mdio_delay(offset); + OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset); + mdio_delay(offset); + } +} + +static int +mdio_read(struct eth_device *dev, int phy_id, int addr) +{ + int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr; + int i, retval = 0; + + /* Shift the read command bits out. */ + for (i = 15; i >= 0; i--) { + int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; + + OUTL(dev, dataval, EECtrl); + mdio_delay(EECtrl); + OUTL(dev, dataval | MDIO_ShiftClk, EECtrl); + mdio_delay(EECtrl); + } + /* Read the two transition, 16 data, and wire-idle bits. */ + for (i = 19; i > 0; i--) { + OUTL(dev, MDIO_EnbIn, EECtrl); + mdio_delay(EECtrl); + retval = + (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0); + OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl); + mdio_delay(EECtrl); + } + return (retval >> 1) & 0xffff; +} + +static void +mdio_write(struct eth_device *dev, int phy_id, int addr, int value) +{ + int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value; + int i; + + /* Shift the command bits out. */ + for (i = 31; i >= 0; i--) { + int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; + + OUTL(dev, dataval, EECtrl); + mdio_delay(EECtrl); + OUTL(dev, dataval | MDIO_ShiftClk, EECtrl); + mdio_delay(EECtrl); + } + /* Clear out extra bits. */ + for (i = 2; i > 0; i--) { + OUTL(dev, MDIO_EnbIn, EECtrl); + mdio_delay(EECtrl); + OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl); + mdio_delay(EECtrl); + } + return; +} + +/* Function: ns8382x_init + * Description: resets the ethernet controller chip and configures + * registers and data structures required for sending and receiving packets. + * Arguments: struct eth_device *dev: NIC data structure + * returns: int. + */ + +static int +ns8382x_init(struct eth_device *dev, bd_t * bis) +{ + u32 config; + + ns8382x_reset(dev); + + /* Disable PME: + * The PME bit is initialized from the EEPROM contents. + * PCI cards probably have PME disabled, but motherboard + * implementations may have PME set to enable WakeOnLan. + * With PME set the chip will scan incoming packets but + * nothing will be written to memory. */ + OUTL(dev, SavedClkRun & ~0x100, ClkRun); + + ns8382x_init_rxfilter(dev); + ns8382x_init_txd(dev); + ns8382x_init_rxd(dev); + + /*set up ChipConfig */ + config = INL(dev, ChipConfig); + /*turn off 64 bit ops && Ten-bit interface + * && big-endian mode && extended status */ + config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn); + OUTL(dev, config, ChipConfig); + + /* Configure the PCI bus bursts and FIFO thresholds. */ + tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad + | TxCollRetry | TxMxdma_1024 | (0x1002); + rx_config = RxMxdma_1024 | 0x20; +#ifdef NS8382X_DEBUG + printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config); + printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config); +#endif + OUTL(dev, tx_config, TxConfig); + OUTL(dev, rx_config, RxConfig); + + /*turn off priority queueing */ + OUTL(dev, 0x0, PriQueue); + + ns8382x_check_duplex(dev); + ns8382x_set_rx_mode(dev); + + OUTL(dev, (RxOn | TxOn), ChipCmd); + return 1; +} + +/* Function: ns8382x_reset + * Description: soft resets the controller chip + * Arguments: struct eth_device *dev: NIC data structure + * Returns: void. + */ +static void +ns8382x_reset(struct eth_device *dev) +{ + OUTL(dev, ChipReset, ChipCmd); + while (INL(dev, ChipCmd)) + /*wait until done */ ; + OUTL(dev, 0, IntrMask); + OUTL(dev, 0, IntrEnable); +} + +/* Function: ns8382x_init_rxfilter + * Description: sets receive filter address to our MAC address + * Arguments: struct eth_device *dev: NIC data structure + * returns: void. + */ + +static void +ns8382x_init_rxfilter(struct eth_device *dev) +{ + int i; + + for (i = 0; i < ETH_ALEN; i += 2) { + OUTL(dev, i, RxFilterAddr); + OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8), + RxFilterData); + } +} + +/* Function: ns8382x_init_txd + * Description: initializes the Tx descriptor + * Arguments: struct eth_device *dev: NIC data structure + * returns: void. + */ + +static void +ns8382x_init_txd(struct eth_device *dev) +{ + txd.link = (u32) 0; + txd.bufptr = cpu_to_le32((u32) & txb[0]); + txd.cmdsts = (u32) 0; + txd.extsts = (u32) 0; + + OUTL(dev, 0x0, TxRingPtrHi); + OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr); +#ifdef NS8382X_DEBUG + printf("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n", + INL(dev, TxRingPtr), &txd); +#endif +} + +/* Function: ns8382x_init_rxd + * Description: initializes the Rx descriptor ring + * Arguments: struct eth_device *dev: NIC data structure + * Returns: void. + */ + +static void +ns8382x_init_rxd(struct eth_device *dev) +{ + int i; + + OUTL(dev, 0x0, RxRingPtrHi); + + cur_rx = 0; + for (i = 0; i < NUM_RX_DESC; i++) { + rxd[i].link = + cpu_to_le32((i + 1 < + NUM_RX_DESC) ? (u32) & rxd[i + + 1] : (u32) & + rxd[0]); + rxd[i].extsts = cpu_to_le32((u32) 0x0); + rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE); + rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]); +#ifdef NS8382X_DEBUG + printf + ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n", + i, &rxd[i], le32_to_cpu(rxd[i].link), + le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr)); +#endif + } + OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr); + +#ifdef NS8382X_DEBUG + printf("ns8382x_init_rxd: RX descriptor register loaded with: %X\n", + INL(dev, RxRingPtr)); +#endif +} + +/* Function: ns8382x_set_rx_mode + * Description: + * sets the receive mode to accept all broadcast packets and packets + * with our MAC address, and reject all multicast packets. + * Arguments: struct eth_device *dev: NIC data structure + * Returns: void. + */ + +static void +ns8382x_set_rx_mode(struct eth_device *dev) +{ + u32 rx_mode = 0x0; + /*spec says RxFilterEnable has to be 0 for rest of + * this stuff to be properly configured. Linux driver + * seems to support this*/ +/* OUTL(dev, rx_mode, RxFilterAddr);*/ + rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch); + OUTL(dev, rx_mode, RxFilterAddr); + printf("ns8382x_set_rx_mode: set to %X\n", rx_mode); + /*now we turn RxFilterEnable back on */ + /*rx_mode |= RxFilterEnable; + OUTL(dev, rx_mode, RxFilterAddr);*/ +} + +static void +ns8382x_check_duplex(struct eth_device *dev) +{ + int gig = 0; + int hun = 0; + int duplex = 0; + int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity); + + duplex = (config & FullDuplex) ? 1 : 0; + gig = (config & GigSpeed) ? 1 : 0; + hun = (config & HundSpeed) ? 1 : 0; +#ifdef NS8382X_DEBUG + printf("%s: Setting 10%s %s-duplex based on negotiated link" + " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "", + duplex ? "full" : "half"); +#endif + if (duplex) { + rx_config |= RxAcceptTx; + tx_config |= (TxCarrierIgn | TxHeartIgn); + } else { + rx_config &= ~RxAcceptTx; + tx_config &= ~(TxCarrierIgn | TxHeartIgn); + } +#ifdef NS8382X_DEBUG + printf("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config); + printf("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config); +#endif + OUTL(dev, tx_config, TxConfig); + OUTL(dev, rx_config, RxConfig); + + /*if speed is 10 or 100, remove MODE1000, + * if it's 1000, then set it */ + config = INL(dev, ChipConfig); + if (gig) + config |= Mode1000; + else + config &= ~Mode1000; + +#ifdef NS8382X_DEBUG + printf("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns"); +#endif + OUTL(dev, config, ChipConfig); +} + +/* Function: ns8382x_send + * Description: transmits a packet and waits for completion or timeout. + * Returns: void. */ +static int +ns8382x_send(struct eth_device *dev, volatile void *packet, int length) +{ + u32 i, status = 0; + u32 tx_stat = 0; + + /* Stop the transmitter */ + OUTL(dev, TxOff, ChipCmd); +#ifdef NS8382X_DEBUG + printf("ns8382x_send: sending %d bytes\n", (int)length); +#endif + + /* set the transmit buffer descriptor and enable Transmit State Machine */ + txd.link = cpu_to_le32(0x0); + txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet)); + txd.extsts = cpu_to_le32(0x0); + txd.cmdsts = cpu_to_le32(DescOwn | length); + + /* load Transmit Descriptor Register */ + OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr); +#ifdef NS8382X_DEBUG + printf("ns8382x_send: TX descriptor register loaded with: %#08X\n", + INL(dev, TxRingPtr)); + printf("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n", + le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr), + le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts)); +#endif + /* restart the transmitter */ + OUTL(dev, TxOn, ChipCmd); + + for (i = 0; ((vu_long)tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) { + if (i >= TOUT_LOOP) { + printf ("%s: tx error buffer not ready: txd.cmdsts %#X\n", + dev->name, tx_stat); + goto Done; + } + } + + if (!(tx_stat & DescPktOK)) { + printf("ns8382x_send: Transmit error, Tx status %X.\n", tx_stat); + goto Done; + } +#ifdef NS8382X_DEBUG + printf("ns8382x_send: tx_stat: %#08X\n", tx_stat); +#endif + + status = 1; + Done: + return status; +} + +/* Function: ns8382x_poll + * Description: checks for a received packet and returns it if found. + * Arguments: struct eth_device *dev: NIC data structure + * Returns: 1 if packet was received. + * 0 if no packet was received. + * Side effects: + * Returns (copies) the packet to the array dev->packet. + * Returns the length of the packet. + */ + +static int +ns8382x_poll(struct eth_device *dev) +{ + int retstat = 0; + int length = 0; + vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts); + + if (!(rx_status & (u32) DescOwn)) + return retstat; +#ifdef NS8382X_DEBUG + printf("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n", + cur_rx, rx_status); +#endif + length = (rx_status & DSIZE) - CRC_SIZE; + + if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) { + /* corrupted packet received */ + printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status); + retstat = 0; + } else { + /* give packet to higher level routine */ + NetReceive((rxb + cur_rx * RX_BUF_SIZE), length); + retstat = 1; + } + + /* return the descriptor and buffer to receive ring */ + rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE); + rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]); + + if (++cur_rx == NUM_RX_DESC) + cur_rx = 0; + + /* re-enable the potentially idle receive state machine */ + OUTL(dev, RxOn, ChipCmd); + + return retstat; +} + +/* Function: ns8382x_disable + * Description: Turns off interrupts and stops Tx and Rx engines + * Arguments: struct eth_device *dev: NIC data structure + * Returns: void. + */ + +static void +ns8382x_disable(struct eth_device *dev) +{ + /* Disable interrupts using the mask. */ + OUTL(dev, 0, IntrMask); + OUTL(dev, 0, IntrEnable); + + /* Stop the chip's Tx and Rx processes. */ + OUTL(dev, (RxOff | TxOff), ChipCmd); + + /* Restore PME enable bit */ + OUTL(dev, SavedClkRun, ClkRun); +} + +#endif diff --git a/drivers/smc91111.c b/drivers/smc91111.c new file mode 100644 index 0000000..62d2133 --- /dev/null +++ b/drivers/smc91111.c @@ -0,0 +1,1383 @@ +/*------------------------------------------------------------------------ + . smc91111.c + . This is a driver for SMSC's 91C111 single-chip Ethernet device. + . + . (C) Copyright 2002 + . Sysgo Real-Time Solutions, GmbH <www.elinos.com> + . Rolf Offermanns <rof@sysgo.de> + . + . Copyright (C) 2001 Standard Microsystems Corporation (SMSC) + . Developed by Simple Network Magic Corporation (SNMC) + . Copyright (C) 1996 by Erik Stahlman (ES) + . + . 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 + . + . Information contained in this file was obtained from the LAN91C111 + . manual from SMC. To get a copy, if you really want one, you can find + . information under www.smsc.com. + . + . + . "Features" of the SMC chip: + . Integrated PHY/MAC for 10/100BaseT Operation + . Supports internal and external MII + . Integrated 8K packet memory + . EEPROM interface for configuration + . + . Arguments: + . io = for the base address + . irq = for the IRQ + . + . author: + . Erik Stahlman ( erik@vt.edu ) + . Daris A Nevil ( dnevil@snmc.com ) + . + . + . Hardware multicast code from Peter Cammaert ( pc@denkart.be ) + . + . Sources: + . o SMSC LAN91C111 databook (www.smsc.com) + . o smc9194.c by Erik Stahlman + . o skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov ) + . + . History: + . 10/17/01 Marco Hasewinkel Modify for DNP/1110 + . 07/25/01 Woojung Huh Modify for ADS Bitsy + . 04/25/01 Daris A Nevil Initial public release through SMSC + . 03/16/01 Daris A Nevil Modified smc9194.c for use with LAN91C111 + ----------------------------------------------------------------------------*/ + +#include <common.h> +#include <command.h> +#include "smc91111.h" +#include <net.h> + +#ifdef CONFIG_DRIVER_SMC91111 + +/* Use power-down feature of the chip */ +#define POWER_DOWN 0 + +#define NO_AUTOPROBE + +static const char version[] = + "smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n"; + +#define SMC_DEBUG 0 + +/*------------------------------------------------------------------------ + . + . Configuration options, for the experienced user to change. + . + -------------------------------------------------------------------------*/ + +/* + . Wait time for memory to be free. This probably shouldn't be + . tuned that much, as waiting for this means nothing else happens + . in the system +*/ +#define MEMORY_WAIT_TIME 16 + + +#if (SMC_DEBUG > 2 ) +#define PRINTK3(args...) printf(args) +#else +#define PRINTK3(args...) +#endif + +#if SMC_DEBUG > 1 +#define PRINTK2(args...) printf(args) +#else +#define PRINTK2(args...) +#endif + +#ifdef SMC_DEBUG +#define PRINTK(args...) printf(args) +#else +#define PRINTK(args...) +#endif + + +/*------------------------------------------------------------------------ + . + . The internal workings of the driver. If you are changing anything + . here with the SMC stuff, you should have the datasheet and know + . what you are doing. + . + -------------------------------------------------------------------------*/ +#define CARDNAME "LAN91C111" + +/* Memory sizing constant */ +#define LAN91C111_MEMORY_MULTIPLIER (1024*2) + +#ifndef CONFIG_SMC91111_BASE +#define CONFIG_SMC91111_BASE 0x20000300 +#endif + +#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE + +#define SMC_DEV_NAME "SMC91111" +#define SMC_PHY_ADDR 0x0000 +#define SMC_ALLOC_MAX_TRY 5 +#define SMC_TX_TIMEOUT 30 + +#define SMC_PHY_CLOCK_DELAY 1000 + +#define ETH_ZLEN 60 + +#ifdef CONFIG_SMC_USE_32_BIT +#define USE_32_BIT 1 +#else +#undef USE_32_BIT +#endif +/*----------------------------------------------------------------- + . + . The driver can be entered at any of the following entry points. + . + .------------------------------------------------------------------ */ + +extern int eth_init(bd_t *bd); +extern void eth_halt(void); +extern int eth_rx(void); +extern int eth_send(volatile void *packet, int length); + + + + + +/* + . This is called by register_netdev(). It is responsible for + . checking the portlist for the SMC9000 series chipset. If it finds + . one, then it will initialize the device, find the hardware information, + . and sets up the appropriate device parameters. + . NOTE: Interrupts are *OFF* when this procedure is called. + . + . NB:This shouldn't be static since it is referred to externally. +*/ +int smc_init(void); + +/* + . This is called by unregister_netdev(). It is responsible for + . cleaning up before the driver is finally unregistered and discarded. +*/ +void smc_destructor(void); + +/* + . The kernel calls this function when someone wants to use the device, + . typically 'ifconfig ethX up'. +*/ +static int smc_open(void); + + +/* + . This is called by the kernel in response to 'ifconfig ethX down'. It + . is responsible for cleaning up everything that the open routine + . does, and maybe putting the card into a powerdown state. +*/ +static int smc_close(void); + +/* + . Configures the PHY through the MII Management interface +*/ +#ifndef CONFIG_SMC91111_EXT_PHY +static void smc_phy_configure(void); +#endif /* !CONFIG_SMC91111_EXT_PHY */ + +/* + . This is a separate procedure to handle the receipt of a packet, to + . leave the interrupt code looking slightly cleaner +*/ +static int smc_rcv(void); + + + +/* + ------------------------------------------------------------ + . + . Internal routines + . + ------------------------------------------------------------ +*/ + +static char smc_mac_addr[] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8}; + +/* + * This function must be called before smc_open() if you want to override + * the default mac address. + */ + +void smc_set_mac_addr(const char *addr) { + int i; + + for (i=0; i < sizeof(smc_mac_addr); i++){ + smc_mac_addr[i] = addr[i]; + } +} + +/* + * smc_get_macaddr is no longer used. If you want to override the default + * mac address, call smc_get_mac_addr as a part of the board initialisation. + */ + +#if 0 +void smc_get_macaddr( byte *addr ) { + /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */ + unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010); + int i; + + + for (i=0; i<6; i++) { + addr[0] = *(dnp1110_mac+0); + addr[1] = *(dnp1110_mac+1); + addr[2] = *(dnp1110_mac+2); + addr[3] = *(dnp1110_mac+3); + addr[4] = *(dnp1110_mac+4); + addr[5] = *(dnp1110_mac+5); + } +} +#endif /* 0 */ + +/*********************************************** + * Show available memory * + ***********************************************/ +void dump_memory_info(void) +{ + word mem_info; + word old_bank; + + old_bank = SMC_inw(BANK_SELECT)&0xF; + + SMC_SELECT_BANK(0); + mem_info = SMC_inw( MIR_REG ); + PRINTK2("Memory: %4d available\n", (mem_info >> 8)*2048); + + SMC_SELECT_BANK(old_bank); +} +/* + . A rather simple routine to print out a packet for debugging purposes. +*/ +#if SMC_DEBUG > 2 +static void print_packet( byte *, int ); +#endif + +#define tx_done(dev) 1 + + + +/* this does a soft reset on the device */ +static void smc_reset( void ); + +/* Enable Interrupts, Receive, and Transmit */ +static void smc_enable( void ); + +/* this puts the device in an inactive state */ +static void smc_shutdown( void ); + +/* Routines to Read and Write the PHY Registers across the + MII Management Interface +*/ + +#ifndef CONFIG_SMC91111_EXT_PHY +static word smc_read_phy_register(byte phyreg); +static void smc_write_phy_register(byte phyreg, word phydata); +#endif /* !CONFIG_SMC91111_EXT_PHY */ + + +static int poll4int( byte mask, int timeout ) { + int tmo = get_timer(0) + timeout * CFG_HZ; + int is_timeout = 0; + word old_bank = SMC_inw(BSR_REG); + + PRINTK2("Polling...\n"); + SMC_SELECT_BANK(2); + while((SMC_inw(SMC91111_INT_REG) & mask) == 0) + { + if (get_timer(0) >= tmo) { + is_timeout = 1; + break; + } + } + + /* restore old bank selection */ + SMC_SELECT_BANK(old_bank); + + if (is_timeout) + return 1; + else + return 0; +} + +/* + . Function: smc_reset( void ) + . Purpose: + . This sets the SMC91111 chip to its normal state, hopefully from whatever + . mess that any other DOS driver has put it in. + . + . Maybe I should reset more registers to defaults in here? SOFTRST should + . do that for me. + . + . Method: + . 1. send a SOFT RESET + . 2. wait for it to finish + . 3. enable autorelease mode + . 4. reset the memory management unit + . 5. clear all interrupts + . +*/ +static void smc_reset( void ) +{ + PRINTK2("%s:smc_reset\n", SMC_DEV_NAME); + + /* This resets the registers mostly to defaults, but doesn't + affect EEPROM. That seems unnecessary */ + SMC_SELECT_BANK( 0 ); + SMC_outw( RCR_SOFTRST, RCR_REG ); + + /* Setup the Configuration Register */ + /* This is necessary because the CONFIG_REG is not affected */ + /* by a soft reset */ + + SMC_SELECT_BANK( 1 ); +#if defined(CONFIG_SMC91111_EXT_PHY) + SMC_outw( CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG); +#else + SMC_outw( CONFIG_DEFAULT, CONFIG_REG); +#endif + + + /* Release from possible power-down state */ + /* Configuration register is not affected by Soft Reset */ + SMC_outw( SMC_inw( CONFIG_REG ) | CONFIG_EPH_POWER_EN, CONFIG_REG ); + + SMC_SELECT_BANK( 0 ); + + /* this should pause enough for the chip to be happy */ + udelay(10); + + /* Disable transmit and receive functionality */ + SMC_outw( RCR_CLEAR, RCR_REG ); + SMC_outw( TCR_CLEAR, TCR_REG ); + + /* set the control register */ + SMC_SELECT_BANK( 1 ); + SMC_outw( CTL_DEFAULT, CTL_REG ); + + /* Reset the MMU */ + SMC_SELECT_BANK( 2 ); + SMC_outw( MC_RESET, MMU_CMD_REG ); + while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY ) + udelay(1); /* Wait until not busy */ + + /* Note: It doesn't seem that waiting for the MMU busy is needed here, + but this is a place where future chipsets _COULD_ break. Be wary + of issuing another MMU command right after this */ + + /* Disable all interrupts */ + SMC_outb( 0, IM_REG ); +} + +/* + . Function: smc_enable + . Purpose: let the chip talk to the outside work + . Method: + . 1. Enable the transmitter + . 2. Enable the receiver + . 3. Enable interrupts +*/ +static void smc_enable() +{ + PRINTK2("%s:smc_enable\n", SMC_DEV_NAME); + SMC_SELECT_BANK( 0 ); + /* see the header file for options in TCR/RCR DEFAULT*/ + SMC_outw( TCR_DEFAULT, TCR_REG ); + SMC_outw( RCR_DEFAULT, RCR_REG ); + + /* clear MII_DIS */ +/* smc_write_phy_register(PHY_CNTL_REG, 0x0000); */ +} + +/* + . Function: smc_shutdown + . Purpose: closes down the SMC91xxx chip. + . Method: + . 1. zero the interrupt mask + . 2. clear the enable receive flag + . 3. clear the enable xmit flags + . + . TODO: + . (1) maybe utilize power down mode. + . Why not yet? Because while the chip will go into power down mode, + . the manual says that it will wake up in response to any I/O requests + . in the register space. Empirical results do not show this working. +*/ +static void smc_shutdown() +{ + PRINTK2(CARDNAME ":smc_shutdown\n"); + + /* no more interrupts for me */ + SMC_SELECT_BANK( 2 ); + SMC_outb( 0, IM_REG ); + + /* and tell the card to stay away from that nasty outside world */ + SMC_SELECT_BANK( 0 ); + SMC_outb( RCR_CLEAR, RCR_REG ); + SMC_outb( TCR_CLEAR, TCR_REG ); +} + + +/* + . Function: smc_hardware_send_packet(struct net_device * ) + . Purpose: + . This sends the actual packet to the SMC9xxx chip. + . + . Algorithm: + . First, see if a saved_skb is available. + . ( this should NOT be called if there is no 'saved_skb' + . Now, find the packet number that the chip allocated + . Point the data pointers at it in memory + . Set the length word in the chip's memory + . Dump the packet to chip memory + . Check if a last byte is needed ( odd length packet ) + . if so, set the control flag right + . Tell the card to send it + . Enable the transmit interrupt, so I know if it failed + . Free the kernel data if I actually sent it. +*/ +static int smc_send_packet(volatile void *packet, int packet_length) +{ + byte packet_no; + unsigned long ioaddr; + byte * buf; + int length; + int numPages; + int try = 0; + int time_out; + byte status; + + + PRINTK3("%s:smc_hardware_send_packet\n", SMC_DEV_NAME); + + length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN; + + /* allocate memory + ** The MMU wants the number of pages to be the number of 256 bytes + ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) ) + ** + ** The 91C111 ignores the size bits, but the code is left intact + ** for backwards and future compatibility. + ** + ** Pkt size for allocating is data length +6 (for additional status + ** words, length and ctl!) + ** + ** If odd size then last byte is included in this header. + */ + numPages = ((length & 0xfffe) + 6); + numPages >>= 8; /* Divide by 256 */ + + if (numPages > 7 ) { + printf("%s: Far too big packet error. \n", SMC_DEV_NAME); + return 0; + } + + /* now, try to allocate the memory */ + SMC_SELECT_BANK( 2 ); + SMC_outw( MC_ALLOC | numPages, MMU_CMD_REG ); + +again: + try++; + time_out = MEMORY_WAIT_TIME; + do { + status = SMC_inb( SMC91111_INT_REG ); + if ( status & IM_ALLOC_INT ) { + /* acknowledge the interrupt */ + SMC_outb( IM_ALLOC_INT, SMC91111_INT_REG ); + break; + } + } while ( -- time_out ); + + if ( !time_out ) { + PRINTK2("%s: memory allocation, try %d failed ...\n", + SMC_DEV_NAME, try); + if (try < SMC_ALLOC_MAX_TRY) + goto again; + else + return 0; + } + + PRINTK2("%s: memory allocation, try %d succeeded ...\n", + SMC_DEV_NAME, + try); + + /* I can send the packet now.. */ + + ioaddr = SMC_BASE_ADDRESS; + + buf = (byte *)packet; + + /* If I get here, I _know_ there is a packet slot waiting for me */ + packet_no = SMC_inb( AR_REG ); + if ( packet_no & AR_FAILED ) { + /* or isn't there? BAD CHIP! */ + printf("%s: Memory allocation failed. \n", + SMC_DEV_NAME); + return 0; + } + + /* we have a packet address, so tell the card to use it */ + SMC_outb( packet_no, PN_REG ); + + /* point to the beginning of the packet */ + SMC_outw( PTR_AUTOINC , PTR_REG ); + + PRINTK3("%s: Trying to xmit packet of length %x\n", + SMC_DEV_NAME, length); + +#if SMC_DEBUG > 2 + printf("Transmitting Packet\n"); + print_packet( buf, length ); +#endif + + /* send the packet length ( +6 for status, length and ctl byte ) + and the status word ( set to zeros ) */ +#ifdef USE_32_BIT + SMC_outl( (length +6 ) << 16 , SMC91111_DATA_REG ); +#else + SMC_outw( 0, SMC91111_DATA_REG ); + /* send the packet length ( +6 for status words, length, and ctl*/ + SMC_outw( (length+6), SMC91111_DATA_REG ); +#endif + + /* send the actual data + . I _think_ it's faster to send the longs first, and then + . mop up by sending the last word. It depends heavily + . on alignment, at least on the 486. Maybe it would be + . a good idea to check which is optimal? But that could take + . almost as much time as is saved? + */ +#ifdef USE_32_BIT + SMC_outsl(SMC91111_DATA_REG, buf, length >> 2 ); + if ( length & 0x2 ) + SMC_outw(*((word *)(buf + (length & 0xFFFFFFFC))), SMC91111_DATA_REG); +#else + SMC_outsw(SMC91111_DATA_REG , buf, (length ) >> 1); +#endif /* USE_32_BIT */ + + /* Send the last byte, if there is one. */ + if ( (length & 1) == 0 ) { + SMC_outw( 0, SMC91111_DATA_REG ); + } else { + SMC_outw( buf[length -1 ] | 0x2000, SMC91111_DATA_REG ); + } + + /* and let the chipset deal with it */ + SMC_outw( MC_ENQUEUE , MMU_CMD_REG ); + + /* poll for TX INT */ + if (poll4int(IM_TX_INT, SMC_TX_TIMEOUT)) { + /* sending failed */ + PRINTK2("%s: TX timeout, sending failed...\n", + SMC_DEV_NAME); + + /* release packet */ + SMC_outw(MC_FREEPKT, MMU_CMD_REG); + + /* wait for MMU getting ready (low) */ + while (SMC_inw(MMU_CMD_REG) & MC_BUSY) + { + udelay(10); + } + + PRINTK2("MMU ready\n"); + + + return 0; + } else { + /* ack. int */ + SMC_outw(IM_TX_INT, SMC91111_INT_REG); + PRINTK2("%s: Sent packet of length %d \n", SMC_DEV_NAME, length); + + /* release packet */ + SMC_outw(MC_FREEPKT, MMU_CMD_REG); + + /* wait for MMU getting ready (low) */ + while (SMC_inw(MMU_CMD_REG) & MC_BUSY) + { + udelay(10); + } + + PRINTK2("MMU ready\n"); + + + } + + return length; +} + +/*------------------------------------------------------------------------- + | + | smc_destructor( struct net_device * dev ) + | Input parameters: + | dev, pointer to the device structure + | + | Output: + | None. + | + --------------------------------------------------------------------------- +*/ +void smc_destructor() +{ + PRINTK2(CARDNAME ":smc_destructor\n"); +} + + +/* + * Open and Initialize the board + * + * Set up everything, reset the card, etc .. + * + */ +static int smc_open() +{ + int i; /* used to set hw ethernet address */ + + PRINTK2("%s:smc_open\n", SMC_DEV_NAME); + + /* reset the hardware */ + + smc_reset(); + smc_enable(); + + /* Configure the PHY */ +#ifndef CONFIG_SMC91111_EXT_PHY + smc_phy_configure(); +#endif + + + /* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */ +/* SMC_SELECT_BANK(0); */ +/* SMC_outw(0, RPC_REG); */ + +#ifdef USE_32_BIT + for ( i = 0; i < 6; i += 2 ) { + word address; + + address = smc_mac_addr[ i + 1 ] << 8 ; + address |= smc_mac_addr[ i ]; + SMC_outw( address, ADDR0_REG + i ); + } +#else + for ( i = 0; i < 6; i ++ ) + SMC_outb( smc_mac_addr[i], ADDR0_REG + i ); +#endif + + return 0; +} + +#if 0 /* dead code? -- wd */ +#ifdef USE_32_BIT +void +insl32(r,b,l) +{ + int __i ; + dword *__b2; + + __b2 = (dword *) b; + for (__i = 0; __i < l; __i++) { + *(__b2 + __i) = *(dword *)(r+0x10000300); + } +} +#endif +#endif + +/*------------------------------------------------------------- + . + . smc_rcv - receive a packet from the card + . + . There is ( at least ) a packet waiting to be read from + . chip-memory. + . + . o Read the status + . o If an error, record it + . o otherwise, read in the packet + -------------------------------------------------------------- +*/ +static int smc_rcv() +{ + int packet_number; + word status; + word packet_length; + int is_error = 0; +#ifdef USE_32_BIT + dword stat_len; +#endif + + + SMC_SELECT_BANK(2); + packet_number = SMC_inw( RXFIFO_REG ); + + if ( packet_number & RXFIFO_REMPTY ) { + + return 0; + } + + PRINTK3("%s:smc_rcv\n", SMC_DEV_NAME); + /* start reading from the start of the packet */ + SMC_outw( PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG ); + + /* First two words are status and packet_length */ +#ifdef USE_32_BIT + stat_len = SMC_inl(SMC91111_DATA_REG); + status = stat_len & 0xffff; + packet_length = stat_len >> 16; +#else + status = SMC_inw( SMC91111_DATA_REG ); + packet_length = SMC_inw( SMC91111_DATA_REG ); +#endif + + packet_length &= 0x07ff; /* mask off top bits */ + + PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length ); + + if ( !(status & RS_ERRORS ) ){ + /* Adjust for having already read the first two words */ + packet_length -= 4; /*4; */ + + + + /* set odd length for bug in LAN91C111, */ + /* which never sets RS_ODDFRAME */ + /* TODO ? */ + + +#ifdef USE_32_BIT + PRINTK3(" Reading %d dwords (and %d bytes) \n", + packet_length >> 2, packet_length & 3 ); + /* QUESTION: Like in the TX routine, do I want + to send the DWORDs or the bytes first, or some + mixture. A mixture might improve already slow PIO + performance */ + SMC_insl( SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 2 ); + /* read the left over bytes */ + if (packet_length & 3) { + int i; + + byte *tail = NetRxPackets[0] + (packet_length & ~3); + dword leftover = SMC_inl(SMC91111_DATA_REG); + for (i=0; i<(packet_length & 3); i++) + *tail++ = (byte) (leftover >> (8*i)) & 0xff; + } +#else + PRINTK3(" Reading %d words and %d byte(s) \n", + (packet_length >> 1 ), packet_length & 1 ); + SMC_insw(SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 1); + +#endif /* USE_32_BIT */ + +#if SMC_DEBUG > 2 + printf("Receiving Packet\n"); + print_packet( NetRxPackets[0], packet_length ); +#endif + } else { + /* error ... */ + /* TODO ? */ + is_error = 1; + } + + while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY ) + udelay(1); /* Wait until not busy */ + + /* error or good, tell the card to get rid of this packet */ + SMC_outw( MC_RELEASE, MMU_CMD_REG ); + + while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY ) + udelay(1); /* Wait until not busy */ + + if (!is_error) { + /* Pass the packet up to the protocol layers. */ + NetReceive(NetRxPackets[0], packet_length); + return packet_length; + } else { + return 0; + } + +} + + + +/*---------------------------------------------------- + . smc_close + . + . this makes the board clean up everything that it can + . and not talk to the outside world. Caused by + . an 'ifconfig ethX down' + . + -----------------------------------------------------*/ +static int smc_close() +{ + PRINTK2("%s:smc_close\n", SMC_DEV_NAME); + + /* clear everything */ + smc_shutdown(); + + return 0; +} + + +#if 0 +/*------------------------------------------------------------ + . Modify a bit in the LAN91C111 register set + .-------------------------------------------------------------*/ +static word smc_modify_regbit(int bank, int ioaddr, int reg, + unsigned int bit, int val) +{ + word regval; + + SMC_SELECT_BANK( bank ); + + regval = SMC_inw( reg ); + if (val) + regval |= bit; + else + regval &= ~bit; + + SMC_outw( regval, 0 ); + return(regval); +} + + +/*------------------------------------------------------------ + . Retrieve a bit in the LAN91C111 register set + .-------------------------------------------------------------*/ +static int smc_get_regbit(int bank, int ioaddr, int reg, unsigned int bit) +{ + SMC_SELECT_BANK( bank ); + if ( SMC_inw( reg ) & bit) + return(1); + else + return(0); +} + + +/*------------------------------------------------------------ + . Modify a LAN91C111 register (word access only) + .-------------------------------------------------------------*/ +static void smc_modify_reg(int bank, int ioaddr, int reg, word val) +{ + SMC_SELECT_BANK( bank ); + SMC_outw( val, reg ); +} + + +/*------------------------------------------------------------ + . Retrieve a LAN91C111 register (word access only) + .-------------------------------------------------------------*/ +static int smc_get_reg(int bank, int ioaddr, int reg) +{ + SMC_SELECT_BANK( bank ); + return(SMC_inw( reg )); +} + +#endif /* 0 */ + +/*---PHY CONTROL AND CONFIGURATION----------------------------------------- */ + +#if (SMC_DEBUG > 2 ) + +/*------------------------------------------------------------ + . Debugging function for viewing MII Management serial bitstream + .-------------------------------------------------------------*/ +static void smc_dump_mii_stream(byte* bits, int size) +{ + int i; + + printf("BIT#:"); + for (i = 0; i < size; ++i) + { + printf("%d", i%10); + } + + printf("\nMDOE:"); + for (i = 0; i < size; ++i) + { + if (bits[i] & MII_MDOE) + printf("1"); + else + printf("0"); + } + + printf("\nMDO :"); + for (i = 0; i < size; ++i) + { + if (bits[i] & MII_MDO) + printf("1"); + else + printf("0"); + } + + printf("\nMDI :"); + for (i = 0; i < size; ++i) + { + if (bits[i] & MII_MDI) + printf("1"); + else + printf("0"); + } + + printf("\n"); +} +#endif + +/*------------------------------------------------------------ + . Reads a register from the MII Management serial interface + .-------------------------------------------------------------*/ +#ifndef CONFIG_SMC91111_EXT_PHY +static word smc_read_phy_register(byte phyreg) +{ + int oldBank; + int i; + byte mask; + word mii_reg; + byte bits[64]; + int clk_idx = 0; + int input_idx; + word phydata; + byte phyaddr = SMC_PHY_ADDR; + + /* 32 consecutive ones on MDO to establish sync */ + for (i = 0; i < 32; ++i) + bits[clk_idx++] = MII_MDOE | MII_MDO; + + /* Start code <01> */ + bits[clk_idx++] = MII_MDOE; + bits[clk_idx++] = MII_MDOE | MII_MDO; + + /* Read command <10> */ + bits[clk_idx++] = MII_MDOE | MII_MDO; + bits[clk_idx++] = MII_MDOE; + + /* Output the PHY address, msb first */ + mask = (byte)0x10; + for (i = 0; i < 5; ++i) + { + if (phyaddr & mask) + bits[clk_idx++] = MII_MDOE | MII_MDO; + else + bits[clk_idx++] = MII_MDOE; + + /* Shift to next lowest bit */ + mask >>= 1; + } + + /* Output the phy register number, msb first */ + mask = (byte)0x10; + for (i = 0; i < 5; ++i) + { + if (phyreg & mask) + bits[clk_idx++] = MII_MDOE | MII_MDO; + else + bits[clk_idx++] = MII_MDOE; + + /* Shift to next lowest bit */ + mask >>= 1; + } + + /* Tristate and turnaround (2 bit times) */ + bits[clk_idx++] = 0; + /*bits[clk_idx++] = 0; */ + + /* Input starts at this bit time */ + input_idx = clk_idx; + + /* Will input 16 bits */ + for (i = 0; i < 16; ++i) + bits[clk_idx++] = 0; + + /* Final clock bit */ + bits[clk_idx++] = 0; + + /* Save the current bank */ + oldBank = SMC_inw( BANK_SELECT ); + + /* Select bank 3 */ + SMC_SELECT_BANK( 3 ); + + /* Get the current MII register value */ + mii_reg = SMC_inw( MII_REG ); + + /* Turn off all MII Interface bits */ + mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO); + + /* Clock all 64 cycles */ + for (i = 0; i < sizeof bits; ++i) + { + /* Clock Low - output data */ + SMC_outw( mii_reg | bits[i], MII_REG ); + udelay(SMC_PHY_CLOCK_DELAY); + + + /* Clock Hi - input data */ + SMC_outw( mii_reg | bits[i] | MII_MCLK, MII_REG ); + udelay(SMC_PHY_CLOCK_DELAY); + bits[i] |= SMC_inw( MII_REG ) & MII_MDI; + } + + /* Return to idle state */ + /* Set clock to low, data to low, and output tristated */ + SMC_outw( mii_reg, MII_REG ); + udelay(SMC_PHY_CLOCK_DELAY); + + /* Restore original bank select */ + SMC_SELECT_BANK( oldBank ); + + /* Recover input data */ + phydata = 0; + for (i = 0; i < 16; ++i) + { + phydata <<= 1; + + if (bits[input_idx++] & MII_MDI) + phydata |= 0x0001; + } + +#if (SMC_DEBUG > 2 ) + printf("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n", + phyaddr, phyreg, phydata); + smc_dump_mii_stream(bits, sizeof bits); +#endif + + return(phydata); +} + + +/*------------------------------------------------------------ + . Writes a register to the MII Management serial interface + .-------------------------------------------------------------*/ +static void smc_write_phy_register(byte phyreg, word phydata) +{ + int oldBank; + int i; + word mask; + word mii_reg; + byte bits[65]; + int clk_idx = 0; + byte phyaddr = SMC_PHY_ADDR; + + /* 32 consecutive ones on MDO to establish sync */ + for (i = 0; i < 32; ++i) + bits[clk_idx++] = MII_MDOE | MII_MDO; + + /* Start code <01> */ + bits[clk_idx++] = MII_MDOE; + bits[clk_idx++] = MII_MDOE | MII_MDO; + + /* Write command <01> */ + bits[clk_idx++] = MII_MDOE; + bits[clk_idx++] = MII_MDOE | MII_MDO; + + /* Output the PHY address, msb first */ + mask = (byte)0x10; + for (i = 0; i < 5; ++i) + { + if (phyaddr & mask) + bits[clk_idx++] = MII_MDOE | MII_MDO; + else + bits[clk_idx++] = MII_MDOE; + + /* Shift to next lowest bit */ + mask >>= 1; + } + + /* Output the phy register number, msb first */ + mask = (byte)0x10; + for (i = 0; i < 5; ++i) + { + if (phyreg & mask) + bits[clk_idx++] = MII_MDOE | MII_MDO; + else + bits[clk_idx++] = MII_MDOE; + + /* Shift to next lowest bit */ + mask >>= 1; + } + + /* Tristate and turnaround (2 bit times) */ + bits[clk_idx++] = 0; + bits[clk_idx++] = 0; + + /* Write out 16 bits of data, msb first */ + mask = 0x8000; + for (i = 0; i < 16; ++i) + { + if (phydata & mask) + bits[clk_idx++] = MII_MDOE | MII_MDO; + else + bits[clk_idx++] = MII_MDOE; + + /* Shift to next lowest bit */ + mask >>= 1; + } + + /* Final clock bit (tristate) */ + bits[clk_idx++] = 0; + + /* Save the current bank */ + oldBank = SMC_inw( BANK_SELECT ); + + /* Select bank 3 */ + SMC_SELECT_BANK( 3 ); + + /* Get the current MII register value */ + mii_reg = SMC_inw( MII_REG ); + + /* Turn off all MII Interface bits */ + mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO); + + /* Clock all cycles */ + for (i = 0; i < sizeof bits; ++i) + { + /* Clock Low - output data */ + SMC_outw( mii_reg | bits[i], MII_REG ); + udelay(SMC_PHY_CLOCK_DELAY); + + + /* Clock Hi - input data */ + SMC_outw( mii_reg | bits[i] | MII_MCLK, MII_REG ); + udelay(SMC_PHY_CLOCK_DELAY); + bits[i] |= SMC_inw( MII_REG ) & MII_MDI; + } + + /* Return to idle state */ + /* Set clock to low, data to low, and output tristated */ + SMC_outw( mii_reg, MII_REG ); + udelay(SMC_PHY_CLOCK_DELAY); + + /* Restore original bank select */ + SMC_SELECT_BANK( oldBank ); + +#if (SMC_DEBUG > 2 ) + printf("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n", + phyaddr, phyreg, phydata); + smc_dump_mii_stream(bits, sizeof bits); +#endif +} +#endif /* !CONFIG_SMC91111_EXT_PHY */ + + + +/*------------------------------------------------------------ + . Waits the specified number of milliseconds - kernel friendly + .-------------------------------------------------------------*/ +#ifndef CONFIG_SMC91111_EXT_PHY +static void smc_wait_ms(unsigned int ms) +{ + udelay(ms*1000); +} +#endif /* !CONFIG_SMC91111_EXT_PHY */ + + + +/*------------------------------------------------------------ + . Configures the specified PHY using Autonegotiation. Calls + . smc_phy_fixed() if the user has requested a certain config. + .-------------------------------------------------------------*/ +#ifndef CONFIG_SMC91111_EXT_PHY +static void smc_phy_configure() +{ + int timeout; + byte phyaddr; + word my_phy_caps; /* My PHY capabilities */ + word my_ad_caps; /* My Advertised capabilities */ + word status = 0; /*;my status = 0 */ + int failed = 0; + + PRINTK3("%s:smc_program_phy()\n", SMC_DEV_NAME); + + + + /* Get the detected phy address */ + phyaddr = SMC_PHY_ADDR; + + /* Reset the PHY, setting all other bits to zero */ + smc_write_phy_register(PHY_CNTL_REG, PHY_CNTL_RST); + + /* Wait for the reset to complete, or time out */ + timeout = 6; /* Wait up to 3 seconds */ + while (timeout--) + { + if (!(smc_read_phy_register(PHY_CNTL_REG) + & PHY_CNTL_RST)) + { + /* reset complete */ + break; + } + + smc_wait_ms(500); /* wait 500 millisecs */ + } + + if (timeout < 1) + { + printf("%s:PHY reset timed out\n", SMC_DEV_NAME); + goto smc_phy_configure_exit; + } + + /* Read PHY Register 18, Status Output */ + /* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */ + + /* Enable PHY Interrupts (for register 18) */ + /* Interrupts listed here are disabled */ + smc_write_phy_register(PHY_INT_REG, 0xffff); + + /* Configure the Receive/Phy Control register */ + SMC_SELECT_BANK( 0 ); + SMC_outw( RPC_DEFAULT, RPC_REG ); + + /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */ + my_phy_caps = smc_read_phy_register(PHY_STAT_REG); + my_ad_caps = PHY_AD_CSMA; /* I am CSMA capable */ + + if (my_phy_caps & PHY_STAT_CAP_T4) + my_ad_caps |= PHY_AD_T4; + + if (my_phy_caps & PHY_STAT_CAP_TXF) + my_ad_caps |= PHY_AD_TX_FDX; + + if (my_phy_caps & PHY_STAT_CAP_TXH) + my_ad_caps |= PHY_AD_TX_HDX; + + if (my_phy_caps & PHY_STAT_CAP_TF) + my_ad_caps |= PHY_AD_10_FDX; + + if (my_phy_caps & PHY_STAT_CAP_TH) + my_ad_caps |= PHY_AD_10_HDX; + + /* Update our Auto-Neg Advertisement Register */ + smc_write_phy_register( PHY_AD_REG, my_ad_caps); + + PRINTK2("%s:phy caps=%x\n", SMC_DEV_NAME, my_phy_caps); + PRINTK2("%s:phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps); + + /* Restart auto-negotiation process in order to advertise my caps */ + smc_write_phy_register( PHY_CNTL_REG, + PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST ); + + /* Wait for the auto-negotiation to complete. This may take from */ + /* 2 to 3 seconds. */ + /* Wait for the reset to complete, or time out */ + timeout = 20; /* Wait up to 10 seconds */ + while (timeout--) + { + status = smc_read_phy_register( PHY_STAT_REG); + if (status & PHY_STAT_ANEG_ACK) + { + /* auto-negotiate complete */ + break; + } + + smc_wait_ms(500); /* wait 500 millisecs */ + + /* Restart auto-negotiation if remote fault */ + if (status & PHY_STAT_REM_FLT) + { + printf("%s:PHY remote fault detected\n", SMC_DEV_NAME); + + /* Restart auto-negotiation */ + printf("%s:PHY restarting auto-negotiation\n", + SMC_DEV_NAME); + smc_write_phy_register( PHY_CNTL_REG, + PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST | + PHY_CNTL_SPEED | PHY_CNTL_DPLX); + } + } + + if (timeout < 1) + { + printf("%s:PHY auto-negotiate timed out\n", + SMC_DEV_NAME); + printf("%s:PHY auto-negotiate timed out\n", SMC_DEV_NAME); + failed = 1; + } + + /* Fail if we detected an auto-negotiate remote fault */ + if (status & PHY_STAT_REM_FLT) + { + printf( "%s:PHY remote fault detected\n", SMC_DEV_NAME); + printf("%s:PHY remote fault detected\n", SMC_DEV_NAME); + failed = 1; + } + + /* Re-Configure the Receive/Phy Control register */ + SMC_outw( RPC_DEFAULT, RPC_REG ); + + smc_phy_configure_exit: + +} +#endif /* !CONFIG_SMC91111_EXT_PHY */ + + +#if SMC_DEBUG > 2 +static void print_packet( byte * buf, int length ) +{ +#if 0 + int i; + int remainder; + int lines; + + printf("Packet of length %d \n", length ); + +#if SMC_DEBUG > 3 + lines = length / 16; + remainder = length % 16; + + for ( i = 0; i < lines ; i ++ ) { + int cur; + + for ( cur = 0; cur < 8; cur ++ ) { + byte a, b; + + a = *(buf ++ ); + b = *(buf ++ ); + printf("%02x%02x ", a, b ); + } + printf("\n"); + } + for ( i = 0; i < remainder/2 ; i++ ) { + byte a, b; + + a = *(buf ++ ); + b = *(buf ++ ); + printf("%02x%02x ", a, b ); + } + printf("\n"); +#endif +#endif +} +#endif + +int eth_init(bd_t *bd) { + smc_open(); + return 0; +} + +void eth_halt() { + smc_close(); +} + +int eth_rx() { + return smc_rcv(); +} + +int eth_send(volatile void *packet, int length) { + return smc_send_packet(packet, length); +} + +#endif /* CONFIG_DRIVER_SMC91111 */ diff --git a/drivers/smc91111.h b/drivers/smc91111.h new file mode 100644 index 0000000..a372c27 --- /dev/null +++ b/drivers/smc91111.h @@ -0,0 +1,619 @@ +/*------------------------------------------------------------------------ + . smc91111.h - macros for the LAN91C111 Ethernet Driver + . + . (C) Copyright 2002 + . Sysgo Real-Time Solutions, GmbH <www.elinos.com> + . Rolf Offermanns <rof@sysgo.de> + . Copyright (C) 2001 Standard Microsystems Corporation (SMSC) + . Developed by Simple Network Magic Corporation (SNMC) + . Copyright (C) 1996 by Erik Stahlman (ES) + . + . This program is free software; you can redistribute it and/or modify + . it under the terms of the GNU General Public License as published by + . the Free Software Foundation; either version 2 of the License, or + . (at your option) any later version. + . + . This program is distributed in the hope that it will be useful, + . but WITHOUT ANY WARRANTY; without even the implied warranty of + . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + . GNU General Public License for more details. + . + . You should have received a copy of the GNU General Public License + . along with this program; if not, write to the Free Software + . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + . + . This file contains register information and access macros for + . the LAN91C111 single chip ethernet controller. It is a modified + . version of the smc9194.h file. + . + . Information contained in this file was obtained from the LAN91C111 + . manual from SMC. To get a copy, if you really want one, you can find + . information under www.smsc.com. + . + . Authors + . Erik Stahlman ( erik@vt.edu ) + . Daris A Nevil ( dnevil@snmc.com ) + . + . History + . 03/16/01 Daris A Nevil Modified for use with LAN91C111 device + . + ---------------------------------------------------------------------------*/ +#ifndef _SMC91111_H_ +#define _SMC91111_H_ + +#include <asm/types.h> +#include <config.h> + +/* + * This function may be called by the board specific initialisation code + * in order to override the default mac address. + */ + +void smc_set_mac_addr(const char *addr); + + +/* I want some simple types */ + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long int dword; + +/* + . DEBUGGING LEVELS + . + . 0 for normal operation + . 1 for slightly more details + . >2 for various levels of increasingly useless information + . 2 for interrupt tracking, status flags + . 3 for packet info + . 4 for complete packet dumps +*/ +/*#define SMC_DEBUG 0 */ + +/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */ + +#define SMC_IO_EXTENT 16 + +#ifdef CONFIG_PXA250 + +#define SMC_inl(r) (*((volatile dword *)(SMC_BASE_ADDRESS+(r)))) +#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r)))) +#define SMC_inb(p) ({ \ + unsigned int __p = (unsigned int)(SMC_BASE_ADDRESS + (p)); \ + unsigned int __v = *(volatile unsigned short *)((SMC_BASE_ADDRESS + __p) & ~1); \ + if (__p & 1) __v >>= 8; \ + else __v &= 0xff; \ + __v; }) + +#define SMC_outl(d,r) (*((volatile dword *)(SMC_BASE_ADDRESS+(r))) = d) +#define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d) +#define SMC_outb(d,r) ({ word __d = (byte)(d); \ + word __w = SMC_inw((r)&~1); \ + __w &= ((r)&1) ? 0x00FF : 0xFF00; \ + __w |= ((r)&1) ? __d<<8 : __d; \ + SMC_outw(__w,(r)&~1); \ + }) + +#define SMC_outsl(r,b,l) ({ int __i; \ + dword *__b2; \ + __b2 = (dword *) b; \ + for (__i = 0; __i < l; __i++) { \ + SMC_outl( *(__b2 + __i), r); \ + } \ + }) + +#define SMC_outsw(r,b,l) ({ int __i; \ + word *__b2; \ + __b2 = (word *) b; \ + for (__i = 0; __i < l; __i++) { \ + SMC_outw( *(__b2 + __i), r); \ + } \ + }) + +#define SMC_insl(r,b,l) ({ int __i ; \ + dword *__b2; \ + __b2 = (dword *) b; \ + for (__i = 0; __i < l; __i++) { \ + *(__b2 + __i) = SMC_inl(r); \ + SMC_inl(0); \ + }; \ + }) + +#define SMC_insw(r,b,l) ({ int __i ; \ + word *__b2; \ + __b2 = (word *) b; \ + for (__i = 0; __i < l; __i++) { \ + *(__b2 + __i) = SMC_inw(r); \ + SMC_inw(0); \ + }; \ + }) + +#define SMC_insb(r,b,l) ({ int __i ; \ + byte *__b2; \ + __b2 = (byte *) b; \ + for (__i = 0; __i < l; __i++) { \ + *(__b2 + __i) = SMC_inb(r); \ + SMC_inb(0); \ + }; \ + }) + +#else /* if not CONFIG_PXA250 */ + +/* + * We have only 16 Bit PCMCIA access on Socket 0 + */ + +#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r)))) +#define SMC_inb(r) (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF) + +#define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d) +#define SMC_outb(d,r) ({ word __d = (byte)(d); \ + word __w = SMC_inw((r)&~1); \ + __w &= ((r)&1) ? 0x00FF : 0xFF00; \ + __w |= ((r)&1) ? __d<<8 : __d; \ + SMC_outw(__w,(r)&~1); \ + }) +#if 0 +#define SMC_outsw(r,b,l) outsw(SMC_BASE_ADDRESS+(r), (b), (l)) +#else +#define SMC_outsw(r,b,l) ({ int __i; \ + word *__b2; \ + __b2 = (word *) b; \ + for (__i = 0; __i < l; __i++) { \ + SMC_outw( *(__b2 + __i), r); \ + } \ + }) +#endif + +#if 0 +#define SMC_insw(r,b,l) insw(SMC_BASE_ADDRESS+(r), (b), (l)) +#else +#define SMC_insw(r,b,l) ({ int __i ; \ + word *__b2; \ + __b2 = (word *) b; \ + for (__i = 0; __i < l; __i++) { \ + *(__b2 + __i) = SMC_inw(r); \ + SMC_inw(0); \ + }; \ + }) +#endif + +#endif + +/*--------------------------------------------------------------- + . + . A description of the SMSC registers is probably in order here, + . although for details, the SMC datasheet is invaluable. + . + . Basically, the chip has 4 banks of registers ( 0 to 3 ), which + . are accessed by writing a number into the BANK_SELECT register + . ( I also use a SMC_SELECT_BANK macro for this ). + . + . The banks are configured so that for most purposes, bank 2 is all + . that is needed for simple run time tasks. + -----------------------------------------------------------------------*/ + +/* + . Bank Select Register: + . + . yyyy yyyy 0000 00xx + . xx = bank number + . yyyy yyyy = 0x33, for identification purposes. +*/ +#define BANK_SELECT 14 + +/* Transmit Control Register */ +/* BANK 0 */ +#define TCR_REG 0x0000 /* transmit control register */ +#define TCR_ENABLE 0x0001 /* When 1 we can transmit */ +#define TCR_LOOP 0x0002 /* Controls output pin LBK */ +#define TCR_FORCOL 0x0004 /* When 1 will force a collision */ +#define TCR_PAD_EN 0x0080 /* When 1 will pad tx frames < 64 bytes w/0 */ +#define TCR_NOCRC 0x0100 /* When 1 will not append CRC to tx frames */ +#define TCR_MON_CSN 0x0400 /* When 1 tx monitors carrier */ +#define TCR_FDUPLX 0x0800 /* When 1 enables full duplex operation */ +#define TCR_STP_SQET 0x1000 /* When 1 stops tx if Signal Quality Error */ +#define TCR_EPH_LOOP 0x2000 /* When 1 enables EPH block loopback */ +#define TCR_SWFDUP 0x8000 /* When 1 enables Switched Full Duplex mode */ + +#define TCR_CLEAR 0 /* do NOTHING */ +/* the default settings for the TCR register : */ +/* QUESTION: do I want to enable padding of short packets ? */ +#define TCR_DEFAULT TCR_ENABLE + + +/* EPH Status Register */ +/* BANK 0 */ +#define EPH_STATUS_REG 0x0002 +#define ES_TX_SUC 0x0001 /* Last TX was successful */ +#define ES_SNGL_COL 0x0002 /* Single collision detected for last tx */ +#define ES_MUL_COL 0x0004 /* Multiple collisions detected for last tx */ +#define ES_LTX_MULT 0x0008 /* Last tx was a multicast */ +#define ES_16COL 0x0010 /* 16 Collisions Reached */ +#define ES_SQET 0x0020 /* Signal Quality Error Test */ +#define ES_LTXBRD 0x0040 /* Last tx was a broadcast */ +#define ES_TXDEFR 0x0080 /* Transmit Deferred */ +#define ES_LATCOL 0x0200 /* Late collision detected on last tx */ +#define ES_LOSTCARR 0x0400 /* Lost Carrier Sense */ +#define ES_EXC_DEF 0x0800 /* Excessive Deferral */ +#define ES_CTR_ROL 0x1000 /* Counter Roll Over indication */ +#define ES_LINK_OK 0x4000 /* Driven by inverted value of nLNK pin */ +#define ES_TXUNRN 0x8000 /* Tx Underrun */ + + +/* Receive Control Register */ +/* BANK 0 */ +#define RCR_REG 0x0004 +#define RCR_RX_ABORT 0x0001 /* Set if a rx frame was aborted */ +#define RCR_PRMS 0x0002 /* Enable promiscuous mode */ +#define RCR_ALMUL 0x0004 /* When set accepts all multicast frames */ +#define RCR_RXEN 0x0100 /* IFF this is set, we can receive packets */ +#define RCR_STRIP_CRC 0x0200 /* When set strips CRC from rx packets */ +#define RCR_ABORT_ENB 0x0200 /* When set will abort rx on collision */ +#define RCR_FILT_CAR 0x0400 /* When set filters leading 12 bit s of carrier */ +#define RCR_SOFTRST 0x8000 /* resets the chip */ + +/* the normal settings for the RCR register : */ +#define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) +#define RCR_CLEAR 0x0 /* set it to a base state */ + +/* Counter Register */ +/* BANK 0 */ +#define COUNTER_REG 0x0006 + +/* Memory Information Register */ +/* BANK 0 */ +#define MIR_REG 0x0008 + +/* Receive/Phy Control Register */ +/* BANK 0 */ +#define RPC_REG 0x000A +#define RPC_SPEED 0x2000 /* When 1 PHY is in 100Mbps mode. */ +#define RPC_DPLX 0x1000 /* When 1 PHY is in Full-Duplex Mode */ +#define RPC_ANEG 0x0800 /* When 1 PHY is in Auto-Negotiate Mode */ +#define RPC_LSXA_SHFT 5 /* Bits to shift LS2A,LS1A,LS0A to lsb */ +#define RPC_LSXB_SHFT 2 /* Bits to get LS2B,LS1B,LS0B to lsb */ +#define RPC_LED_100_10 (0x00) /* LED = 100Mbps OR's with 10Mbps link detect */ +#define RPC_LED_RES (0x01) /* LED = Reserved */ +#define RPC_LED_10 (0x02) /* LED = 10Mbps link detect */ +#define RPC_LED_FD (0x03) /* LED = Full Duplex Mode */ +#define RPC_LED_TX_RX (0x04) /* LED = TX or RX packet occurred */ +#define RPC_LED_100 (0x05) /* LED = 100Mbps link dectect */ +#define RPC_LED_TX (0x06) /* LED = TX packet occurred */ +#define RPC_LED_RX (0x07) /* LED = RX packet occurred */ +#define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) + +/* Bank 0 0x000C is reserved */ + +/* Bank Select Register */ +/* All Banks */ +#define BSR_REG 0x000E + + +/* Configuration Reg */ +/* BANK 1 */ +#define CONFIG_REG 0x0000 +#define CONFIG_EXT_PHY 0x0200 /* 1=external MII, 0=internal Phy */ +#define CONFIG_GPCNTRL 0x0400 /* Inverse value drives pin nCNTRL */ +#define CONFIG_NO_WAIT 0x1000 /* When 1 no extra wait states on ISA bus */ +#define CONFIG_EPH_POWER_EN 0x8000 /* When 0 EPH is placed into low power mode. */ + +/* Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low */ +#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) + + +/* Base Address Register */ +/* BANK 1 */ +#define BASE_REG 0x0002 + + +/* Individual Address Registers */ +/* BANK 1 */ +#define ADDR0_REG 0x0004 +#define ADDR1_REG 0x0006 +#define ADDR2_REG 0x0008 + + +/* General Purpose Register */ +/* BANK 1 */ +#define GP_REG 0x000A + + +/* Control Register */ +/* BANK 1 */ +#define CTL_REG 0x000C +#define CTL_RCV_BAD 0x4000 /* When 1 bad CRC packets are received */ +#define CTL_AUTO_RELEASE 0x0800 /* When 1 tx pages are released automatically */ +#define CTL_LE_ENABLE 0x0080 /* When 1 enables Link Error interrupt */ +#define CTL_CR_ENABLE 0x0040 /* When 1 enables Counter Rollover interrupt */ +#define CTL_TE_ENABLE 0x0020 /* When 1 enables Transmit Error interrupt */ +#define CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */ +#define CTL_RELOAD 0x0002 /* When set reads EEPROM into registers */ +#define CTL_STORE 0x0001 /* When set stores registers into EEPROM */ +#define CTL_DEFAULT (0x1210) + +/* MMU Command Register */ +/* BANK 2 */ +#define MMU_CMD_REG 0x0000 +#define MC_BUSY 1 /* When 1 the last release has not completed */ +#define MC_NOP (0<<5) /* No Op */ +#define MC_ALLOC (1<<5) /* OR with number of 256 byte packets */ +#define MC_RESET (2<<5) /* Reset MMU to initial state */ +#define MC_REMOVE (3<<5) /* Remove the current rx packet */ +#define MC_RELEASE (4<<5) /* Remove and release the current rx packet */ +#define MC_FREEPKT (5<<5) /* Release packet in PNR register */ +#define MC_ENQUEUE (6<<5) /* Enqueue the packet for transmit */ +#define MC_RSTTXFIFO (7<<5) /* Reset the TX FIFOs */ + + +/* Packet Number Register */ +/* BANK 2 */ +#define PN_REG 0x0002 + + +/* Allocation Result Register */ +/* BANK 2 */ +#define AR_REG 0x0003 +#define AR_FAILED 0x80 /* Alocation Failed */ + + +/* RX FIFO Ports Register */ +/* BANK 2 */ +#define RXFIFO_REG 0x0004 /* Must be read as a word */ +#define RXFIFO_REMPTY 0x8000 /* RX FIFO Empty */ + + +/* TX FIFO Ports Register */ +/* BANK 2 */ +#define TXFIFO_REG RXFIFO_REG /* Must be read as a word */ +#define TXFIFO_TEMPTY 0x80 /* TX FIFO Empty */ + + +/* Pointer Register */ +/* BANK 2 */ +#define PTR_REG 0x0006 +#define PTR_RCV 0x8000 /* 1=Receive area, 0=Transmit area */ +#define PTR_AUTOINC 0x4000 /* Auto increment the pointer on each access */ +#define PTR_READ 0x2000 /* When 1 the operation is a read */ + + +/* Data Register */ +/* BANK 2 */ +#define SMC91111_DATA_REG 0x0008 + + +/* Interrupt Status/Acknowledge Register */ +/* BANK 2 */ +#define SMC91111_INT_REG 0x000C + + +/* Interrupt Mask Register */ +/* BANK 2 */ +#define IM_REG 0x000D +#define IM_MDINT 0x80 /* PHY MI Register 18 Interrupt */ +#define IM_ERCV_INT 0x40 /* Early Receive Interrupt */ +#define IM_EPH_INT 0x20 /* Set by Etheret Protocol Handler section */ +#define IM_RX_OVRN_INT 0x10 /* Set by Receiver Overruns */ +#define IM_ALLOC_INT 0x08 /* Set when allocation request is completed */ +#define IM_TX_EMPTY_INT 0x04 /* Set if the TX FIFO goes empty */ +#define IM_TX_INT 0x02 /* Transmit Interrrupt */ +#define IM_RCV_INT 0x01 /* Receive Interrupt */ + + +/* Multicast Table Registers */ +/* BANK 3 */ +#define MCAST_REG1 0x0000 +#define MCAST_REG2 0x0002 +#define MCAST_REG3 0x0004 +#define MCAST_REG4 0x0006 + + +/* Management Interface Register (MII) */ +/* BANK 3 */ +#define MII_REG 0x0008 +#define MII_MSK_CRS100 0x4000 /* Disables CRS100 detection during tx half dup */ +#define MII_MDOE 0x0008 /* MII Output Enable */ +#define MII_MCLK 0x0004 /* MII Clock, pin MDCLK */ +#define MII_MDI 0x0002 /* MII Input, pin MDI */ +#define MII_MDO 0x0001 /* MII Output, pin MDO */ + + +/* Revision Register */ +/* BANK 3 */ +#define REV_REG 0x000A /* ( hi: chip id low: rev # ) */ + + +/* Early RCV Register */ +/* BANK 3 */ +/* this is NOT on SMC9192 */ +#define ERCV_REG 0x000C +#define ERCV_RCV_DISCRD 0x0080 /* When 1 discards a packet being received */ +#define ERCV_THRESHOLD 0x001F /* ERCV Threshold Mask */ + +/* External Register */ +/* BANK 7 */ +#define EXT_REG 0x0000 + + +#define CHIP_9192 3 +#define CHIP_9194 4 +#define CHIP_9195 5 +#define CHIP_9196 6 +#define CHIP_91100 7 +#define CHIP_91100FD 8 +#define CHIP_91111FD 9 + +#if 0 +static const char * chip_ids[ 15 ] = { + NULL, NULL, NULL, + /* 3 */ "SMC91C90/91C92", + /* 4 */ "SMC91C94", + /* 5 */ "SMC91C95", + /* 6 */ "SMC91C96", + /* 7 */ "SMC91C100", + /* 8 */ "SMC91C100FD", + /* 9 */ "SMC91C111", + NULL, NULL, + NULL, NULL, NULL}; +#endif + +/* + . Transmit status bits +*/ +#define TS_SUCCESS 0x0001 +#define TS_LOSTCAR 0x0400 +#define TS_LATCOL 0x0200 +#define TS_16COL 0x0010 + +/* + . Receive status bits +*/ +#define RS_ALGNERR 0x8000 +#define RS_BRODCAST 0x4000 +#define RS_BADCRC 0x2000 +#define RS_ODDFRAME 0x1000 /* bug: the LAN91C111 never sets this on receive */ +#define RS_TOOLONG 0x0800 +#define RS_TOOSHORT 0x0400 +#define RS_MULTICAST 0x0001 +#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) + + +/* PHY Types */ +enum { + PHY_LAN83C183 = 1, /* LAN91C111 Internal PHY */ + PHY_LAN83C180 +}; + + +/* PHY Register Addresses (LAN91C111 Internal PHY) */ + +/* PHY Control Register */ +#define PHY_CNTL_REG 0x00 +#define PHY_CNTL_RST 0x8000 /* 1=PHY Reset */ +#define PHY_CNTL_LPBK 0x4000 /* 1=PHY Loopback */ +#define PHY_CNTL_SPEED 0x2000 /* 1=100Mbps, 0=10Mpbs */ +#define PHY_CNTL_ANEG_EN 0x1000 /* 1=Enable Auto negotiation */ +#define PHY_CNTL_PDN 0x0800 /* 1=PHY Power Down mode */ +#define PHY_CNTL_MII_DIS 0x0400 /* 1=MII 4 bit interface disabled */ +#define PHY_CNTL_ANEG_RST 0x0200 /* 1=Reset Auto negotiate */ +#define PHY_CNTL_DPLX 0x0100 /* 1=Full Duplex, 0=Half Duplex */ +#define PHY_CNTL_COLTST 0x0080 /* 1= MII Colision Test */ + +/* PHY Status Register */ +#define PHY_STAT_REG 0x01 +#define PHY_STAT_CAP_T4 0x8000 /* 1=100Base-T4 capable */ +#define PHY_STAT_CAP_TXF 0x4000 /* 1=100Base-X full duplex capable */ +#define PHY_STAT_CAP_TXH 0x2000 /* 1=100Base-X half duplex capable */ +#define PHY_STAT_CAP_TF 0x1000 /* 1=10Mbps full duplex capable */ +#define PHY_STAT_CAP_TH 0x0800 /* 1=10Mbps half duplex capable */ +#define PHY_STAT_CAP_SUPR 0x0040 /* 1=recv mgmt frames with not preamble */ +#define PHY_STAT_ANEG_ACK 0x0020 /* 1=ANEG has completed */ +#define PHY_STAT_REM_FLT 0x0010 /* 1=Remote Fault detected */ +#define PHY_STAT_CAP_ANEG 0x0008 /* 1=Auto negotiate capable */ +#define PHY_STAT_LINK 0x0004 /* 1=valid link */ +#define PHY_STAT_JAB 0x0002 /* 1=10Mbps jabber condition */ +#define PHY_STAT_EXREG 0x0001 /* 1=extended registers implemented */ + +/* PHY Identifier Registers */ +#define PHY_ID1_REG 0x02 /* PHY Identifier 1 */ +#define PHY_ID2_REG 0x03 /* PHY Identifier 2 */ + +/* PHY Auto-Negotiation Advertisement Register */ +#define PHY_AD_REG 0x04 +#define PHY_AD_NP 0x8000 /* 1=PHY requests exchange of Next Page */ +#define PHY_AD_ACK 0x4000 /* 1=got link code word from remote */ +#define PHY_AD_RF 0x2000 /* 1=advertise remote fault */ +#define PHY_AD_T4 0x0200 /* 1=PHY is capable of 100Base-T4 */ +#define PHY_AD_TX_FDX 0x0100 /* 1=PHY is capable of 100Base-TX FDPLX */ +#define PHY_AD_TX_HDX 0x0080 /* 1=PHY is capable of 100Base-TX HDPLX */ +#define PHY_AD_10_FDX 0x0040 /* 1=PHY is capable of 10Base-T FDPLX */ +#define PHY_AD_10_HDX 0x0020 /* 1=PHY is capable of 10Base-T HDPLX */ +#define PHY_AD_CSMA 0x0001 /* 1=PHY is capable of 802.3 CMSA */ + +/* PHY Auto-negotiation Remote End Capability Register */ +#define PHY_RMT_REG 0x05 +/* Uses same bit definitions as PHY_AD_REG */ + +/* PHY Configuration Register 1 */ +#define PHY_CFG1_REG 0x10 +#define PHY_CFG1_LNKDIS 0x8000 /* 1=Rx Link Detect Function disabled */ +#define PHY_CFG1_XMTDIS 0x4000 /* 1=TP Transmitter Disabled */ +#define PHY_CFG1_XMTPDN 0x2000 /* 1=TP Transmitter Powered Down */ +#define PHY_CFG1_BYPSCR 0x0400 /* 1=Bypass scrambler/descrambler */ +#define PHY_CFG1_UNSCDS 0x0200 /* 1=Unscramble Idle Reception Disable */ +#define PHY_CFG1_EQLZR 0x0100 /* 1=Rx Equalizer Disabled */ +#define PHY_CFG1_CABLE 0x0080 /* 1=STP(150ohm), 0=UTP(100ohm) */ +#define PHY_CFG1_RLVL0 0x0040 /* 1=Rx Squelch level reduced by 4.5db */ +#define PHY_CFG1_TLVL_SHIFT 2 /* Transmit Output Level Adjust */ +#define PHY_CFG1_TLVL_MASK 0x003C +#define PHY_CFG1_TRF_MASK 0x0003 /* Transmitter Rise/Fall time */ + + +/* PHY Configuration Register 2 */ +#define PHY_CFG2_REG 0x11 +#define PHY_CFG2_APOLDIS 0x0020 /* 1=Auto Polarity Correction disabled */ +#define PHY_CFG2_JABDIS 0x0010 /* 1=Jabber disabled */ +#define PHY_CFG2_MREG 0x0008 /* 1=Multiple register access (MII mgt) */ +#define PHY_CFG2_INTMDIO 0x0004 /* 1=Interrupt signaled with MDIO pulseo */ + +/* PHY Status Output (and Interrupt status) Register */ +#define PHY_INT_REG 0x12 /* Status Output (Interrupt Status) */ +#define PHY_INT_INT 0x8000 /* 1=bits have changed since last read */ +#define PHY_INT_LNKFAIL 0x4000 /* 1=Link Not detected */ +#define PHY_INT_LOSSSYNC 0x2000 /* 1=Descrambler has lost sync */ +#define PHY_INT_CWRD 0x1000 /* 1=Invalid 4B5B code detected on rx */ +#define PHY_INT_SSD 0x0800 /* 1=No Start Of Stream detected on rx */ +#define PHY_INT_ESD 0x0400 /* 1=No End Of Stream detected on rx */ +#define PHY_INT_RPOL 0x0200 /* 1=Reverse Polarity detected */ +#define PHY_INT_JAB 0x0100 /* 1=Jabber detected */ +#define PHY_INT_SPDDET 0x0080 /* 1=100Base-TX mode, 0=10Base-T mode */ +#define PHY_INT_DPLXDET 0x0040 /* 1=Device in Full Duplex */ + +/* PHY Interrupt/Status Mask Register */ +#define PHY_MASK_REG 0x13 /* Interrupt Mask */ +/* Uses the same bit definitions as PHY_INT_REG */ + + + +/*------------------------------------------------------------------------- + . I define some macros to make it easier to do somewhat common + . or slightly complicated, repeated tasks. + --------------------------------------------------------------------------*/ + +/* select a register bank, 0 to 3 */ + +#define SMC_SELECT_BANK(x) { SMC_outw( x, BANK_SELECT ); } + +/* this enables an interrupt in the interrupt mask register */ +#define SMC_ENABLE_INT(x) {\ + unsigned char mask;\ + SMC_SELECT_BANK(2);\ + mask = SMC_inb( IM_REG );\ + mask |= (x);\ + SMC_outb( mask, IM_REG ); \ +} + +/* this disables an interrupt from the interrupt mask register */ + +#define SMC_DISABLE_INT(x) {\ + unsigned char mask;\ + SMC_SELECT_BANK(2);\ + mask = SMC_inb( IM_REG );\ + mask &= ~(x);\ + SMC_outb( mask, IM_REG ); \ +} + +/*---------------------------------------------------------------------- + . Define the interrupts that I want to receive from the card + . + . I want: + . IM_EPH_INT, for nasty errors + . IM_RCV_INT, for happy received packets + . IM_RX_OVRN_INT, because I have to kick the receiver + . IM_MDINT, for PHY Register 18 Status Changes + --------------------------------------------------------------------------*/ +#define SMC_INTERRUPT_MASK (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \ + IM_MDINT) + +#endif /* _SMC_91111_H_ */ + diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c new file mode 100644 index 0000000..9bb4f1b --- /dev/null +++ b/fs/jffs2/compr_rtime.c @@ -0,0 +1,91 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001 Red Hat, Inc. + * + * Created by Arjan van de Ven <arjanv@redhat.com> + * + * The original JFFS, from which the design for JFFS2 was derived, + * was designed and implemented by Axis Communications AB. + * + * The contents of this file are subject to the Red Hat eCos Public + * License Version 1.1 (the "Licence"); you may not use this file + * except in compliance with the Licence. You may obtain a copy of + * the Licence at http://www.redhat.com/ + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + * + * The Original Code is JFFS2 - Journalling Flash File System, version 2 + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the RHEPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + * + * $Id: compr_rtime.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $ + * + * + * Very simple lz77-ish encoder. + * + * Theory of operation: Both encoder and decoder have a list of "last + * occurances" for every possible source-value; after sending the + * first source-byte, the second byte indicated the "run" length of + * matches + * + * The algorithm is intended to only send "whole bytes", no bit-messing. + * + */ + +#include <config.h> +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +#include <jffs2/jffs2.h> + +void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, + u32 srclen, u32 destlen) +{ + int positions[256]; + int outpos; + int pos; + int i; + + outpos = pos = 0; + + for (i = 0; i < 256; positions[i++] = 0); + + while (outpos<destlen) { + unsigned char value; + int backoffs; + int repeat; + + value = data_in[pos++]; + cpage_out[outpos++] = value; /* first the verbatim copied byte */ + repeat = data_in[pos++]; + backoffs = positions[value]; + + positions[value]=outpos; + if (repeat) { + if (backoffs + repeat >= outpos) { + while(repeat) { + cpage_out[outpos++] = cpage_out[backoffs++]; + repeat--; + } + } else { + for (i = 0; i < repeat; i++) + *(cpage_out + outpos + i) = *(cpage_out + backoffs + i); + outpos+=repeat; + } + } + } +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c new file mode 100644 index 0000000..cf01f88 --- /dev/null +++ b/fs/jffs2/compr_rubin.c @@ -0,0 +1,124 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001 Red Hat, Inc. + * + * Created by Arjan van de Ven <arjanv@redhat.com> + * + * Heavily modified by Russ Dill <Russ.Dill@asu.edu> in an attempt at + * a little more speed. + * + * The original JFFS, from which the design for JFFS2 was derived, + * was designed and implemented by Axis Communications AB. + * + * The contents of this file are subject to the Red Hat eCos Public + * License Version 1.1 (the "Licence"); you may not use this file + * except in compliance with the Licence. You may obtain a copy of + * the Licence at http://www.redhat.com/ + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + * + * The Original Code is JFFS2 - Journalling Flash File System, version 2 + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the RHEPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + * + * $Id: compr_rubin.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $ + * + */ + +#include <config.h> +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +#include <jffs2/jffs2.h> +#include <jffs2/compr_rubin.h> + + +void rubin_do_decompress(unsigned char *bits, unsigned char *in, + unsigned char *page_out, __u32 destlen) +{ + register char *curr = page_out; + char *end = page_out + destlen; + register unsigned long temp; + register unsigned long result; + register unsigned long p; + register unsigned long q; + register unsigned long rec_q; + register unsigned long bit; + register long i0; + unsigned long i; + + /* init_pushpull */ + temp = *(u32 *) in; + bit = 16; + + /* init_rubin */ + q = 0; + p = (long) (2 * UPPER_BIT_RUBIN); + + /* init_decode */ + rec_q = (in[0] << 8) | in[1]; + + while (curr < end) { + /* in byte */ + + result = 0; + for (i = 0; i < 8; i++) { + /* decode */ + + while ((q & UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)) { + q &= ~UPPER_BIT_RUBIN; + q <<= 1; + p <<= 1; + rec_q &= ~UPPER_BIT_RUBIN; + rec_q <<= 1; + rec_q |= (temp >> (bit++ ^ 7)) & 1; + if (bit > 31) { + bit = 0; + temp = *(++((u32 *) in)); + } + } + i0 = (bits[i] * p) >> 8; + + if (i0 <= 0) i0 = 1; + /* if it fails, it fails, we have our crc + if (i0 >= p) i0 = p - 1; */ + + result >>= 1; + if (rec_q < q + i0) { + /* result |= 0x00; */ + p = i0; + } else { + result |= 0x80; + p -= i0; + q += i0; + } + } + *(curr++) = result; + } +} + +void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, + unsigned long sourcelen, unsigned long dstlen) +{ + unsigned char bits[8]; + int c; + + for (c=0; c<8; c++) + bits[c] = (256 - data_in[c]); + + rubin_do_decompress(bits, data_in+8, cpage_out, dstlen); +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c new file mode 100644 index 0000000..1b35585 --- /dev/null +++ b/fs/jffs2/compr_zlib.c @@ -0,0 +1,52 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001 Red Hat, Inc. + * + * Created by David Woodhouse <dwmw2@cambridge.redhat.com> + * + * The original JFFS, from which the design for JFFS2 was derived, + * was designed and implemented by Axis Communications AB. + * + * The contents of this file are subject to the Red Hat eCos Public + * License Version 1.1 (the "Licence"); you may not use this file + * except in compliance with the Licence. You may obtain a copy of + * the Licence at http://www.redhat.com/ + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + * + * The Original Code is JFFS2 - Journalling Flash File System, version 2 + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the RHEPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + * + * $Id: compr_zlib.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $ + * + */ + +#include <common.h> +#include <config.h> +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +#include <jffs2/jffs2.h> +#include <jffs2/mini_inflate.h> + +long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, + __u32 srclen, __u32 destlen) +{ + return (decompress_block(cpage_out, data_in + 2, ldr_memcpy)); + +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c new file mode 100644 index 0000000..bacec8e --- /dev/null +++ b/fs/jffs2/jffs2_1pass.c @@ -0,0 +1,995 @@ +/* +------------------------------------------------------------------------- + * Filename: jffs2.c + * Version: $Id: jffs2_1pass.c,v 1.7 2002/01/25 01:56:47 nyet Exp $ + * Copyright: Copyright (C) 2001, Russ Dill + * Author: Russ Dill <Russ.Dill@asu.edu> + * Description: Module to load kernel from jffs2 + *-----------------------------------------------------------------------*/ +/* + * some portions of this code are taken from jffs2, and as such, the + * following copyright notice is included. + * + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001 Red Hat, Inc. + * + * Created by David Woodhouse <dwmw2@cambridge.redhat.com> + * + * The original JFFS, from which the design for JFFS2 was derived, + * was designed and implemented by Axis Communications AB. + * + * The contents of this file are subject to the Red Hat eCos Public + * License Version 1.1 (the "Licence"); you may not use this file + * except in compliance with the Licence. You may obtain a copy of + * the Licence at http://www.redhat.com/ + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + * + * The Original Code is JFFS2 - Journalling Flash File System, version 2 + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the RHEPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + * + * $Id: jffs2_1pass.c,v 1.7 2002/01/25 01:56:47 nyet Exp $ + * + */ + +/* Ok, so anyone who knows the jffs2 code will probably want to get a papar + * bag to throw up into before reading this code. I looked through the jffs2 + * code, the caching scheme is very elegant. I tried to keep the version + * for a bootloader as small and simple as possible. Instead of worring about + * unneccesary data copies, node scans, etc, I just optimized for the known + * common case, a kernel, which looks like: + * (1) most pages are 4096 bytes + * (2) version numbers are somewhat sorted in acsending order + * (3) multiple compressed blocks making up one page is uncommon + * + * So I create a linked list of decending version numbers (insertions at the + * head), and then for each page, walk down the list, until a matching page + * with 4096 bytes is found, and then decompress the watching pages in + * reverse order. + * + */ + +/* + * Adapted by Nye Liu <nyet@zumanetworks.com> and + * Rex Feany <rfeany@zumanetworks.com> + * on Jan/2002 for U-Boot. + * + * Clipped out all the non-1pass functions, cleaned up warnings, + * wrappers, etc. No major changes to the code. + * Please, he really means it when he said have a paper bag + * handy. We needed it ;). + * + */ + +#include <common.h> +#include <config.h> +#include <malloc.h> +#include <linux/stat.h> +#include <linux/time.h> + +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) + +#include <jffs2/jffs2.h> +#include <jffs2/jffs2_1pass.h> + +#include "jffs2_private.h" + +/* Compression names */ +static char *compr_names[] = { + "NONE", + "ZERO", + "RTIME", + "RUBINMIPS", + "COPY", + "DYNRUBIN", + "ZLIB" }; + +static char spinner[] = { '|', '\\', '-', '/' }; + +#define DEBUG +#ifdef DEBUG +# define DEBUGF(fmt,args...) printf(fmt ,##args) +#else +# define DEBUGF(fmt,args...) +#endif + +#define MALLOC_CHUNK (10*1024) + + +static struct b_node * +add_node(struct b_node *tail, u32 * count, u32 * memBase) +{ + u32 index; + u32 memLimit; + struct b_node *b; + + index = (*count) * sizeof(struct b_node) % MALLOC_CHUNK; + memLimit = MALLOC_CHUNK; + +#if 0 + putLabeledWord("add_node: index = ", index); + putLabeledWord("add_node: memLimit = ", memLimit); + putLabeledWord("add_node: memBase = ", *memBase); +#endif + + /* we need not keep a list of bases since we'll never free the */ + /* memory, just jump the the kernel */ + if ((index == 0) || (index > memLimit)) { /* we need mode space before we continue */ + if ((*memBase = (u32) mmalloc(MALLOC_CHUNK)) == (u32) NULL) { + putstr("add_node: malloc failed\n"); + return NULL; + } +#if 0 + putLabeledWord("add_node: alloced a new membase at ", *memBase); +#endif + + } + /* now we have room to add it. */ + b = (struct b_node *) (*memBase + index); + + /* null on first call */ + if (tail) + tail->next = b; + +#if 0 + putLabeledWord("add_node: tail = ", (u32) tail); + if (tail) + putLabeledWord("add_node: tail->next = ", (u32) tail->next); + +#endif + +#if 0 + putLabeledWord("add_node: mb+i = ", (u32) (*memBase + index)); + putLabeledWord("add_node: b = ", (u32) b); +#endif + (*count)++; + b->next = (struct b_node *) NULL; + return b; + +} + +/* we know we have empties at the start offset so we will hop */ +/* t points that would be non F if there were a node here to speed this up. */ +struct jffs2_empty_node { + u32 first; + u32 second; +}; + +static u32 +jffs2_scan_empty(u32 start_offset, struct part_info *part) +{ + u32 max = part->size - sizeof(struct jffs2_raw_inode); + + /* this would be either dir node_crc or frag isize */ + u32 offset = start_offset + 32; + struct jffs2_empty_node *node; + + start_offset += 4; + while (offset < max) { + node = (struct jffs2_empty_node *) (part->offset + offset); + if ((node->first == 0xFFFFFFFF) && (node->second == 0xFFFFFFFF)) { + /* we presume that there were no nodes in between and advance in a hop */ + /* putLabeledWord("\t\tjffs2_scan_empty: empty at offset=",offset); */ + start_offset = offset + 4; + offset = start_offset + 32; /* orig 32 + 4 bytes for the second==0xfffff */ + } else { + return start_offset; + } + } + return start_offset; +} + +static u32 +jffs_init_1pass_list(struct part_info *part) +{ + if ( 0 != ( part->jffs2_priv=malloc(sizeof(struct b_lists)))){ + struct b_lists *pL =(struct b_lists *)part->jffs2_priv; + + pL->dirListHead = pL->dirListTail = NULL; + pL->fragListHead = pL->fragListTail = NULL; + pL->dirListCount = 0; + pL->dirListMemBase = 0; + pL->fragListCount = 0; + pL->fragListMemBase = 0; + pL->partOffset = 0x0; + } + return 0; +} + +/* find the inode from the slashless name given a parent */ +static long +jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) +{ + struct b_node *b; + struct jffs2_raw_inode *jNode; + u32 totalSize = 1; + u32 oldTotalSize = 0; + u32 size = 0; + char *lDest = (char *) dest; + char *src; + long ret; + int i; + u32 counter = 0; + char totalSizeSet = 0; + +#if 0 + b = pL->fragListHead; + while (b) { + jNode = (struct jffs2_raw_inode *) (b->offset); + if ((inode == jNode->ino)) { + putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen); + putLabeledWord("read_inode: inode = ", jNode->ino); + putLabeledWord("read_inode: version = ", jNode->version); + putLabeledWord("read_inode: isize = ", jNode->isize); + putLabeledWord("read_inode: offset = ", jNode->offset); + putLabeledWord("read_inode: csize = ", jNode->csize); + putLabeledWord("read_inode: dsize = ", jNode->dsize); + putLabeledWord("read_inode: compr = ", jNode->compr); + putLabeledWord("read_inode: usercompr = ", jNode->usercompr); + putLabeledWord("read_inode: flags = ", jNode->flags); + } + + b = b->next; + } + +#endif + +#if 1 + b = pL->fragListHead; + while (b && (size < totalSize)) { + jNode = (struct jffs2_raw_inode *) (b->offset); + if ((inode == jNode->ino)) { + if ((jNode->isize == oldTotalSize) && (jNode->isize > totalSize)) { + /* 2 consecutive isizes indicate file length */ + totalSize = jNode->isize; + totalSizeSet = 1; + } else if (!totalSizeSet) { + totalSize = size + jNode->dsize + 1; + } + oldTotalSize = jNode->isize; + + if(dest) { + src = ((char *) jNode) + sizeof(struct jffs2_raw_inode); + /* lDest = (char *) (dest + (jNode->offset & ~3)); */ + lDest = (char *) (dest + jNode->offset); +#if 0 + putLabeledWord("\r\n\r\nread_inode: src = ", src); + putLabeledWord("read_inode: dest = ", lDest); + putLabeledWord("read_inode: dsize = ", jNode->dsize); + putLabeledWord("read_inode: csize = ", jNode->csize); + putLabeledWord("read_inode: version = ", jNode->version); + putLabeledWord("read_inode: isize = ", jNode->isize); + putLabeledWord("read_inode: offset = ", jNode->offset); + putLabeledWord("read_inode: compr = ", jNode->compr); + putLabeledWord("read_inode: flags = ", jNode->flags); +#endif + switch (jNode->compr) { + case JFFS2_COMPR_NONE: +#if 0 + { + int i; + + if ((dest > 0xc0092ff0) && (dest < 0xc0093000)) + for (i = 0; i < first->length; i++) { + putLabeledWord("\tCOMPR_NONE: src =", src + i); + putLabeledWord("\tCOMPR_NONE: length =", first->length); + putLabeledWord("\tCOMPR_NONE: dest =", dest + i); + putLabeledWord("\tCOMPR_NONE: data =", (unsigned char) *(src + i)); + } + } +#endif + + ret = (unsigned long) ldr_memcpy(lDest, src, jNode->dsize); + break; + case JFFS2_COMPR_ZERO: + ret = 0; + for (i = 0; i < jNode->dsize; i++) + *(lDest++) = 0; + break; + case JFFS2_COMPR_RTIME: + ret = 0; + rtime_decompress(src, lDest, jNode->csize, jNode->dsize); + break; + case JFFS2_COMPR_DYNRUBIN: + /* this is slow but it works */ + ret = 0; + dynrubin_decompress(src, lDest, jNode->csize, jNode->dsize); + break; + case JFFS2_COMPR_ZLIB: + ret = zlib_decompress(src, lDest, jNode->csize, jNode->dsize); + break; + default: + /* unknown */ + putLabeledWord("UNKOWN COMPRESSION METHOD = ", jNode->compr); + return -1; + break; + } + } + + size += jNode->dsize; +#if 0 + putLabeledWord("read_inode: size = ", size); + putLabeledWord("read_inode: totalSize = ", totalSize); + putLabeledWord("read_inode: compr ret = ", ret); +#endif + } + b = b->next; + counter++; + } +#endif + +#if 0 + putLabeledWord("read_inode: returning = ", size); +#endif + return size; +} + +/* find the inode from the slashless name given a parent */ +static u32 +jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) +{ + struct b_node *b; + struct jffs2_raw_dirent *jDir; + int len; + u32 counter; + u32 version = 0; + u32 inode = 0; + + /* name is assumed slash free */ + len = strlen(name); + + counter = 0; + /* we need to search all and return the inode with the highest version */ + for(b = pL->dirListHead;b;b=b->next,counter++) { + jDir = (struct jffs2_raw_dirent *) (b->offset); + if ((pino == jDir->pino) && (len == jDir->nsize) && (jDir->ino) && /* 0 for unlink */ + (!strncmp(jDir->name, name, len))) { /* a match */ + if (jDir->version < version) continue; + + if(jDir->version==0) { + /* Is this legal? */ + putstr(" ** WARNING ** "); + putnstr(jDir->name, jDir->nsize); + putstr(" is version 0 (in find, ignoring)\r\n"); + } else if(jDir->version==version) { + /* Im pretty sure this isn't ... */ + putstr(" ** ERROR ** "); + putnstr(jDir->name, jDir->nsize); + putLabeledWord(" has dup version =", version); + } + inode = jDir->ino; + version = jDir->version; + } +#if 0 + putstr("\r\nfind_inode:p&l ->"); + putnstr(jDir->name, jDir->nsize); + putstr("\r\n"); + putLabeledWord("pino = ", jDir->pino); + putLabeledWord("nsize = ", jDir->nsize); + putLabeledWord("b = ", (u32) b); + putLabeledWord("counter = ", counter); +#endif + } + return inode; +} + +static char *mkmodestr(unsigned long mode, char *str) +{ + static const char *l="xwr"; + int mask=1, i; + char c; + + switch (mode & S_IFMT) { + case S_IFDIR: str[0]='d'; break; + case S_IFBLK: str[0]='b'; break; + case S_IFCHR: str[0]='c'; break; + case S_IFIFO: str[0]='f'; break; + case S_IFLNK: str[0]='l'; break; + case S_IFSOCK: str[0]='s'; break; + case S_IFREG: str[0]='-'; break; + default: str[0]='?'; + } + + for(i=0;i<9;i++) { + c=l[i%3]; + str[9-i]=(mode & mask)?c:'-'; + mask=mask<<1; + } + + if(mode & S_ISUID) str[3]=(mode & S_IXUSR)?'s':'S'; + if(mode & S_ISGID) str[6]=(mode & S_IXGRP)?'s':'S'; + if(mode & S_ISVTX) str[9]=(mode & S_IXOTH)?'t':'T'; + str[10]='\0'; + return str; +} + +static inline void dump_stat(struct stat *st, const char *name) +{ + char str[20]; + char s[64], *p; + + if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */ + st->st_mtime = 1; + + ctime_r(&st->st_mtime, s/*, 64*/); /* newlib ctime doesn't have buflen */ + + if((p=strchr(s,'\n'))!=NULL) *p='\0'; + if((p=strchr(s,'\r'))!=NULL) *p='\0'; + +/* + printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), + st->st_size, s, name); +*/ + + printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name); +} + +static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, struct jffs2_raw_inode *i) +{ + char fname[256]; + struct stat st; + + if(!d || !i) return -1; + + strncpy(fname, d->name, d->nsize); + fname[d->nsize]='\0'; + + memset(&st,0,sizeof(st)); + + st.st_mtime=i->mtime; + st.st_mode=i->mode; + st.st_ino=i->ino; + + /* neither dsize nor isize help us.. do it the long way */ + st.st_size=jffs2_1pass_read_inode(pL, i->ino, NULL); + + dump_stat(&st, fname); + + if (d->type == DT_LNK) { + unsigned char *src = (unsigned char *) (&i[1]); + putstr(" -> "); + putnstr(src, (int)i->dsize); + } + + putstr("\r\n"); + + return 0; +} + +/* list inodes with the given pino */ +static u32 +jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) +{ + struct b_node *b; + struct jffs2_raw_dirent *jDir; + + for(b = pL->dirListHead;b;b=b->next) { + jDir = (struct jffs2_raw_dirent *) (b->offset); + if ((pino == jDir->pino) && (jDir->ino)) { /* 0 inode for unlink */ + u32 i_version=0; + struct jffs2_raw_inode *jNode, *i=NULL; + struct b_node *b2 = pL->fragListHead; + + while (b2) { + jNode = (struct jffs2_raw_inode *) (b2->offset); + if (jNode->ino == jDir->ino + && jNode->version>=i_version) + i=jNode; + b2 = b2->next; + } + + dump_inode(pL, jDir, i); + } + } + return pino; +} + +static u32 +jffs2_1pass_search_inode(struct b_lists * pL, const char *fname, u32 pino) +{ + int i; + char tmp[256]; + char working_tmp[256]; + char *c; + + /* discard any leading slash */ + i = 0; + while (fname[i] == '/') + i++; + strcpy(tmp, &fname[i]); + + while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ + { + strncpy(working_tmp, tmp, c - tmp); + working_tmp[c - tmp] = '\0'; +#if 0 + putstr("search_inode: tmp = "); + putstr(tmp); + putstr("\r\n"); + putstr("search_inode: wtmp = "); + putstr(working_tmp); + putstr("\r\n"); + putstr("search_inode: c = "); + putstr(c); + putstr("\r\n"); +#endif + for (i = 0; i < strlen(c) - 1; i++) + tmp[i] = c[i + 1]; + tmp[i] = '\0'; +#if 0 + putstr("search_inode: post tmp = "); + putstr(tmp); + putstr("\r\n"); +#endif + + if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) { + putstr("find_inode failed for name="); + putstr(working_tmp); + putstr("\r\n"); + return 0; + } + } + /* this is for the bare filename, directories have already been mapped */ + if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { + putstr("find_inode failed for name="); + putstr(tmp); + putstr("\r\n"); + return 0; + } + return pino; + +} + +static u32 +jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) +{ + struct b_node *b; + struct b_node *b2; + struct jffs2_raw_dirent *jDir; + struct jffs2_raw_inode *jNode; + struct jffs2_raw_dirent *jDirFound = NULL; + char tmp[256]; + u32 version = 0; + u32 pino; + unsigned char *src; + + /* we need to search all and return the inode with the highest version */ + for(b = pL->dirListHead; b; b=b->next) { + jDir = (struct jffs2_raw_dirent *) (b->offset); + if (ino == jDir->ino) { + if(jDir->version < version) continue; + + if(jDir->version == 0) { + /* Is this legal? */ + putstr(" ** WARNING ** "); + putnstr(jDir->name, jDir->nsize); + putstr(" is version 0 (in resolve, ignoring)\r\n"); + } else if(jDir->version == version) { + /* Im pretty sure this isn't ... */ + putstr(" ** ERROR ** "); + putnstr(jDir->name, jDir->nsize); + putLabeledWord(" has dup version (resolve) = ", + version); + } + + jDirFound = jDir; + version = jDir->version; + } + } + /* now we found the right entry again. (shoulda returned inode*) */ + if (jDirFound->type != DT_LNK) + return jDirFound->ino; + /* so its a soft link so we follow it again. */ + b2 = pL->fragListHead; + while (b2) { + jNode = (struct jffs2_raw_inode *) (b2->offset); + if (jNode->ino == jDirFound->ino) { + src = (unsigned char *) (b2->offset + sizeof(struct jffs2_raw_inode)); + +#if 0 + putLabeledWord("\t\t dsize = ", jNode->dsize); + putstr("\t\t target = "); + putnstr(src, jNode->dsize); + putstr("\r\n"); +#endif + strncpy(tmp, src, jNode->dsize); + tmp[jNode->dsize] = '\0'; + break; + } + b2 = b2->next; + } + /* ok so the name of the new file to find is in tmp */ + /* if it starts with a slash it is root based else shared dirs */ + if (tmp[0] == '/') + pino = 1; + else + pino = jDirFound->pino; + + return jffs2_1pass_search_inode(pL, tmp, pino); +} + +static u32 +jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino) +{ + int i; + char tmp[256]; + char working_tmp[256]; + char *c; + + /* discard any leading slash */ + i = 0; + while (fname[i] == '/') + i++; + strcpy(tmp, &fname[i]); + working_tmp[0] = '\0'; + while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ + { + strncpy(working_tmp, tmp, c - tmp); + working_tmp[c - tmp] = '\0'; + for (i = 0; i < strlen(c) - 1; i++) + tmp[i] = c[i + 1]; + tmp[i] = '\0'; + /* only a failure if we arent looking at top level */ + if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && (working_tmp[0])) { + putstr("find_inode failed for name="); + putstr(working_tmp); + putstr("\r\n"); + return 0; + } + } + + if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { + putstr("find_inode failed for name="); + putstr(tmp); + putstr("\r\n"); + return 0; + } + /* this is for the bare filename, directories have already been mapped */ + if (!(pino = jffs2_1pass_list_inodes(pL, pino))) { + putstr("find_inode failed for name="); + putstr(tmp); + putstr("\r\n"); + return 0; + } + return pino; + +} + +unsigned char +jffs2_1pass_rescan_needed(struct part_info *part) +{ + struct b_node *b; + struct jffs2_unknown_node *node; + struct b_lists *pL=(struct b_lists *)part->jffs2_priv; + + if (part->jffs2_priv == 0){ + DEBUGF ("rescan: First time in use\n"); + return 1; + } + /* if we have no list, we need to rescan */ + if (pL->fragListCount == 0) { + DEBUGF ("rescan: fraglist zero\n"); + return 1; + } + + /* or if we are scanninga new partition */ + if (pL->partOffset != part->offset) { + DEBUGF ("rescan: different partition\n"); + return 1; + } + /* but suppose someone reflashed the root partition at the same offset... */ + b = pL->dirListHead; + while (b) { + node = (struct jffs2_unknown_node *) (b->offset); + if (node->nodetype != JFFS2_NODETYPE_DIRENT) { + DEBUGF ("rescan: fs changed beneath me? (%lx)\n", (unsigned long) b->offset); + return 1; + } + b = b->next; + } + return 0; +} + +static u32 +jffs2_1pass_build_lists(struct part_info * part) +{ + struct b_lists *pL; + struct jffs2_unknown_node *node; + u32 offset; + u32 max = part->size - sizeof(struct jffs2_raw_inode); + u32 counter = 0; + u32 counter4 = 0; + u32 counterF = 0; + u32 counterN = 0; + + /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ + /* jffs2 list building enterprise nope. in newer versions the overhead is */ + /* only about 5 %. not enough to inconvenience people for. */ + /* lcd_off(); */ + + /* if we are building a list we need to refresh the cache. */ + /* note that since we don't free our memory, eventually this will be bad. */ + /* but we're a bootldr so what the hell. */ + jffs_init_1pass_list(part); + pL=(struct b_lists *)part->jffs2_priv; + pL->partOffset = part->offset; + offset = 0; + printf("Scanning JFFS2 FS: "); + + /* start at the beginning of the partition */ + while (offset < max) { + if (! (++counter%10000)) + printf("\b\b%c ", spinner[(counter / 10000) % 4]); + + node = (struct jffs2_unknown_node *) (part->offset + offset); + if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) { + /* if its a fragment add it */ + if (node->nodetype == JFFS2_NODETYPE_INODE && inode_crc((struct jffs2_raw_inode *) node)) { + if (!(pL->fragListTail = add_node(pL->fragListTail, &(pL->fragListCount), + &(pL->fragListMemBase)))) { + putstr("add_node failed!\r\n"); + return 0; + } + pL->fragListTail->offset = (u32) (part->offset + offset); + if (!pL->fragListHead) + pL->fragListHead = pL->fragListTail; + } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && + dirent_crc((struct jffs2_raw_dirent *) node) && + dirent_name_crc((struct jffs2_raw_dirent *) node)) { + if (! (counterN%100)) + printf("\b\b. "); +#if 0 + printf("Found DIRENT @ 0x%lx\n", offset); + putstr("\r\nbuild_lists:p&l ->"); + putnstr(((struct jffs2_raw_dirent *) node)->name, ((struct jffs2_raw_dirent *) node)->nsize); + putstr("\r\n"); + putLabeledWord("\tpino = ", ((struct jffs2_raw_dirent *) node)->pino); + putLabeledWord("\tnsize = ", ((struct jffs2_raw_dirent *) node)->nsize); +#endif + + if (!(pL->dirListTail = add_node(pL->dirListTail, &(pL->dirListCount), &(pL->dirListMemBase)))) { + putstr("add_node failed!\r\n"); + return 0; + } + pL->dirListTail->offset = (u32) (part->offset + offset); +#if 0 + putLabeledWord("\ttail = ", (u32) pL->dirListTail); + putstr("\ttailName ->"); + putnstr(((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->name, + ((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->nsize); + putstr("\r\n"); +#endif + if (!pL->dirListHead) + pL->dirListHead = pL->dirListTail; + counterN++; + } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { + if (node->totlen != sizeof(struct jffs2_unknown_node)) + printf("OOPS Cleanmarker has bad size %d != %d\n", node->totlen, sizeof(struct jffs2_unknown_node)); + } else { + printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, node->totlen, offset); + } + offset += ((node->totlen + 3) & ~3); + counterF++; + } else if (node->magic == JFFS2_EMPTY_BITMASK && node->nodetype == JFFS2_EMPTY_BITMASK) { + offset = jffs2_scan_empty(offset, part); + } else { /* if we know nothing of the filesystem, we just step and look. */ + offset += 4; + counter4++; + } +/* printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */ + + } + + putstr("\b\b done.\r\n"); /* close off the dots */ + /* turn the lcd back on. */ + /* splash(); */ + +#if 0 + putLabeledWord("dir entries = ", pL->dirListCount); + putLabeledWord("frag entries = ", pL->fragListCount); + putLabeledWord("+4 increments = ", counter4); + putLabeledWord("+file_offset increments = ", counterF); + +#endif + +#undef SHOW_ALL +#undef SHOW_ALL_FRAGMENTS + +#ifdef SHOW_ALL + { + struct b_node *b; + struct b_node *b2; + struct jffs2_raw_dirent *jDir; + struct jffs2_raw_inode *jNode; + + putstr("\r\n\r\n******The directory Entries******\r\n"); + b = pL->dirListHead; + while (b) { + jDir = (struct jffs2_raw_dirent *) (b->offset); + putstr("\r\n"); + putnstr(jDir->name, jDir->nsize); + putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); + putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); + putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); + putLabeledWord("\tbuild_list: pino = ", jDir->pino); + putLabeledWord("\tbuild_list: version = ", jDir->version); + putLabeledWord("\tbuild_list: ino = ", jDir->ino); + putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); + putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); + putLabeledWord("\tbuild_list: type = ", jDir->type); + putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); + putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); + b = b->next; + } + +#ifdef SHOW_ALL_FRAGMENTS + putstr("\r\n\r\n******The fragment Entries******\r\n"); + b = pL->fragListHead; + while (b) { + jNode = (struct jffs2_raw_inode *) (b->offset); + putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); + putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); + putLabeledWord("\tbuild_list: inode = ", jNode->ino); + putLabeledWord("\tbuild_list: version = ", jNode->version); + putLabeledWord("\tbuild_list: isize = ", jNode->isize); + putLabeledWord("\tbuild_list: atime = ", jNode->atime); + putLabeledWord("\tbuild_list: offset = ", jNode->offset); + putLabeledWord("\tbuild_list: csize = ", jNode->csize); + putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); + putLabeledWord("\tbuild_list: compr = ", jNode->compr); + putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); + putLabeledWord("\tbuild_list: flags = ", jNode->flags); + b = b->next; + } +#endif /* SHOW_ALL_FRAGMENTS */ + } + +#endif /* SHOW_ALL */ + /* give visual feedback that we are done scanning the flash */ + led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */ + return 1; +} + + + + + +static u32 +jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL) +{ + struct b_node *b; + struct jffs2_raw_inode *jNode; + int i; + + b = pL->fragListHead; + for (i = 0; i < JFFS2_NUM_COMPR; i++) { + piL->compr_info[i].num_frags = 0; + piL->compr_info[i].compr_sum = 0; + piL->compr_info[i].decompr_sum = 0; + } + + while (b) { + jNode = (struct jffs2_raw_inode *) (b->offset); + if (jNode->compr < JFFS2_NUM_COMPR) { + piL->compr_info[jNode->compr].num_frags++; + piL->compr_info[jNode->compr].compr_sum += jNode->csize; + piL->compr_info[jNode->compr].decompr_sum += jNode->dsize; + } + b = b->next; + } + return 0; +} + + + +static struct b_lists * +jffs2_get_list(struct part_info * part, const char *who) +{ + if (jffs2_1pass_rescan_needed(part)) { + if (!jffs2_1pass_build_lists(part)) { + printf("%s: Failed to scan JFFSv2 file structure\n", who); + return NULL; + } + } + return (struct b_lists *)part->jffs2_priv; +} + + +/* Print directory / file contents */ +u32 +jffs2_1pass_ls(struct part_info * part, const char *fname) +{ + struct b_lists *pl; + long ret = 0; + u32 inode; + + if (! (pl = jffs2_get_list(part, "ls"))) + return 0; + + if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) { + putstr("ls: Failed to scan jffs2 file structure\r\n"); + return 0; + } + + +#if 0 + putLabeledWord("found file at inode = ", inode); + putLabeledWord("read_inode returns = ", ret); +#endif + + return ret; +} + + + + + +/* Load a file from flash into memory. fname can be a full path */ +u32 +jffs2_1pass_load(char *dest, struct part_info * part, const char *fname) +{ + + struct b_lists *pl; + long ret = 0; + u32 inode; + + if (! (pl = jffs2_get_list(part, "load"))) + return 0; + + if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) { + putstr("load: Failed to find inode\r\n"); + return 0; + } + + /* Resolve symlinks */ + if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) { + putstr("load: Failed to resolve inode structure\r\n"); + return 0; + } + + if ((ret = jffs2_1pass_read_inode(pl, inode, dest)) < 0) { + putstr("load: Failed to read inode\r\n"); + return 0; + } + + DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname, + (unsigned long) dest, ret); + return ret; +} + +/* Return information about the fs on this partition */ +u32 +jffs2_1pass_info(struct part_info * part) +{ + struct b_jffs2_info info; + struct b_lists *pl; + int i; + + if (! (pl = jffs2_get_list(part, "info"))) + return 0; + + jffs2_1pass_fill_info(pl, &info); + for (i=0; i < JFFS2_NUM_COMPR; i++) { + printf("Compression: %s\n", compr_names[i]); + printf("\tfrag count: %d\n", info.compr_info[i].num_frags); + printf("\tcompressed sum: %d\n", info.compr_info[i].compr_sum); + printf("\tuncompressed sum: %d\n", info.compr_info[i].decompr_sum); + } + return 1; +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/include/asm-ppc/pnp.h b/include/asm-ppc/pnp.h new file mode 100644 index 0000000..15bf7f1 --- /dev/null +++ b/include/asm-ppc/pnp.h @@ -0,0 +1,643 @@ +/* 11/02/95 */ +/*----------------------------------------------------------------------------*/ +/* Plug and Play header definitions */ +/*----------------------------------------------------------------------------*/ + +/* Structure map for PnP on PowerPC Reference Platform */ +/* See Plug and Play ISA Specification, Version 1.0, May 28, 1993. It */ +/* (or later versions) is available on Compuserve in the PLUGPLAY area. */ +/* This code has extensions to that specification, namely new short and */ +/* long tag types for platform dependent information */ + +/* Warning: LE notation used throughout this file */ + +/* For enum's: if given in hex then they are bit significant, i.e. */ +/* only one bit is on for each enum */ + +#ifndef _PNP_ +#define _PNP_ + +#ifndef __ASSEMBLY__ +#define MAX_MEM_REGISTERS 9 +#define MAX_IO_PORTS 20 +#define MAX_IRQS 7 +/*#define MAX_DMA_CHANNELS 7*/ + +/* Interrupt controllers */ + +#define PNPinterrupt0 "PNP0000" /* AT Interrupt Controller */ +#define PNPinterrupt1 "PNP0001" /* EISA Interrupt Controller */ +#define PNPinterrupt2 "PNP0002" /* MCA Interrupt Controller */ +#define PNPinterrupt3 "PNP0003" /* APIC */ +#define PNPExtInt "IBM000D" /* PowerPC Extended Interrupt Controller */ + +/* Timers */ + +#define PNPtimer0 "PNP0100" /* AT Timer */ +#define PNPtimer1 "PNP0101" /* EISA Timer */ +#define PNPtimer2 "PNP0102" /* MCA Timer */ + +/* DMA controllers */ + +#define PNPdma0 "PNP0200" /* AT DMA Controller */ +#define PNPdma1 "PNP0201" /* EISA DMA Controller */ +#define PNPdma2 "PNP0202" /* MCA DMA Controller */ + +/* start of August 15, 1994 additions */ +/* CMOS */ +#define PNPCMOS "IBM0009" /* CMOS */ + +/* L2 Cache */ +#define PNPL2 "IBM0007" /* L2 Cache */ + +/* NVRAM */ +#define PNPNVRAM "IBM0008" /* NVRAM */ + +/* Power Management */ +#define PNPPM "IBM0005" /* Power Management */ +/* end of August 15, 1994 additions */ + +/* Keyboards */ + +#define PNPkeyboard0 "PNP0300" /* IBM PC/XT KB Cntlr (83 key, no mouse) */ +#define PNPkeyboard1 "PNP0301" /* Olivetti ICO (102 key) */ +#define PNPkeyboard2 "PNP0302" /* IBM PC/AT KB Cntlr (84 key) */ +#define PNPkeyboard3 "PNP0303" /* IBM Enhanced (101/2 key, PS/2 mouse) */ +#define PNPkeyboard4 "PNP0304" /* Nokia 1050 KB Cntlr */ +#define PNPkeyboard5 "PNP0305" /* Nokia 9140 KB Cntlr */ +#define PNPkeyboard6 "PNP0306" /* Standard Japanese KB Cntlr */ +#define PNPkeyboard7 "PNP0307" /* Microsoft Windows (R) KB Cntlr */ + +/* Parallel port controllers */ + +#define PNPparallel0 "PNP0400" /* Standard LPT Parallel Port */ +#define PNPparallel1 "PNP0401" /* ECP Parallel Port */ +#define PNPepp "IBM001C" /* EPP Parallel Port */ + +/* Serial port controllers */ + +#define PNPserial0 "PNP0500" /* Standard PC Serial port */ +#define PNPSerial1 "PNP0501" /* 16550A Compatible Serial port */ + +/* Disk controllers */ + +#define PNPdisk0 "PNP0600" /* Generic ESDI/IDE/ATA Compat HD Cntlr */ +#define PNPdisk1 "PNP0601" /* Plus Hardcard II */ +#define PNPdisk2 "PNP0602" /* Plus Hardcard IIXL/EZ */ + +/* Diskette controllers */ + +#define PNPdiskette0 "PNP0700" /* PC Standard Floppy Disk Controller */ + +/* Display controllers */ + +#define PNPdisplay0 "PNP0900" /* VGA Compatible */ +#define PNPdisplay1 "PNP0901" /* Video Seven VGA */ +#define PNPdisplay2 "PNP0902" /* 8514/A Compatible */ +#define PNPdisplay3 "PNP0903" /* Trident VGA */ +#define PNPdisplay4 "PNP0904" /* Cirrus Logic Laptop VGA */ +#define PNPdisplay5 "PNP0905" /* Cirrus Logic VGA */ +#define PNPdisplay6 "PNP0906" /* Tseng ET4000 or ET4000/W32 */ +#define PNPdisplay7 "PNP0907" /* Western Digital VGA */ +#define PNPdisplay8 "PNP0908" /* Western Digital Laptop VGA */ +#define PNPdisplay9 "PNP0909" /* S3 */ +#define PNPdisplayA "PNP090A" /* ATI Ultra Pro/Plus (Mach 32) */ +#define PNPdisplayB "PNP090B" /* ATI Ultra (Mach 8) */ +#define PNPdisplayC "PNP090C" /* XGA Compatible */ +#define PNPdisplayD "PNP090D" /* ATI VGA Wonder */ +#define PNPdisplayE "PNP090E" /* Weitek P9000 Graphics Adapter */ +#define PNPdisplayF "PNP090F" /* Oak Technology VGA */ + +/* Peripheral busses */ + +#define PNPbuses0 "PNP0A00" /* ISA Bus */ +#define PNPbuses1 "PNP0A01" /* EISA Bus */ +#define PNPbuses2 "PNP0A02" /* MCA Bus */ +#define PNPbuses3 "PNP0A03" /* PCI Bus */ +#define PNPbuses4 "PNP0A04" /* VESA/VL Bus */ + +/* RTC, BIOS, planar devices */ + +#define PNPspeaker0 "PNP0800" /* AT Style Speaker Sound */ +#define PNPrtc0 "PNP0B00" /* AT RTC */ +#define PNPpnpbios0 "PNP0C00" /* PNP BIOS (only created by root enum) */ +#define PNPpnpbios1 "PNP0C01" /* System Board Memory Device */ +#define PNPpnpbios2 "PNP0C02" /* Math Coprocessor */ +#define PNPpnpbios3 "PNP0C03" /* PNP BIOS Event Notification Interrupt */ + +/* PCMCIA controller */ + +#define PNPpcmcia0 "PNP0E00" /* Intel 82365 Compatible PCMCIA Cntlr */ + +/* Mice */ + +#define PNPmouse0 "PNP0F00" /* Microsoft Bus Mouse */ +#define PNPmouse1 "PNP0F01" /* Microsoft Serial Mouse */ +#define PNPmouse2 "PNP0F02" /* Microsoft Inport Mouse */ +#define PNPmouse3 "PNP0F03" /* Microsoft PS/2 Mouse */ +#define PNPmouse4 "PNP0F04" /* Mousesystems Mouse */ +#define PNPmouse5 "PNP0F05" /* Mousesystems 3 Button Mouse - COM2 */ +#define PNPmouse6 "PNP0F06" /* Genius Mouse - COM1 */ +#define PNPmouse7 "PNP0F07" /* Genius Mouse - COM2 */ +#define PNPmouse8 "PNP0F08" /* Logitech Serial Mouse */ +#define PNPmouse9 "PNP0F09" /* Microsoft Ballpoint Serial Mouse */ +#define PNPmouseA "PNP0F0A" /* Microsoft PNP Mouse */ +#define PNPmouseB "PNP0F0B" /* Microsoft PNP Ballpoint Mouse */ + +/* Modems */ + +#define PNPmodem0 "PNP9000" /* Specific IDs TBD */ + +/* Network controllers */ + +#define PNPnetworkC9 "PNP80C9" /* IBM Token Ring */ +#define PNPnetworkCA "PNP80CA" /* IBM Token Ring II */ +#define PNPnetworkCB "PNP80CB" /* IBM Token Ring II/Short */ +#define PNPnetworkCC "PNP80CC" /* IBM Token Ring 4/16Mbs */ +#define PNPnetwork27 "PNP8327" /* IBM Token Ring (All types) */ +#define PNPnetworket "IBM0010" /* IBM Ethernet used by Power PC */ +#define PNPneteisaet "IBM2001" /* IBM Ethernet EISA adapter */ +#define PNPAMD79C970 "IBM0016" /* AMD 79C970 (PCI Ethernet) */ + +/* SCSI controllers */ + +#define PNPscsi0 "PNPA000" /* Adaptec 154x Compatible SCSI Cntlr */ +#define PNPscsi1 "PNPA001" /* Adaptec 174x Compatible SCSI Cntlr */ +#define PNPscsi2 "PNPA002" /* Future Domain 16-700 Compat SCSI Cntlr*/ +#define PNPscsi3 "PNPA003" /* Panasonic CDROM Adapter (SBPro/SB16) */ +#define PNPscsiF "IBM000F" /* NCR 810 SCSI Controller */ +#define PNPscsi825 "IBM001B" /* NCR 825 SCSI Controller */ +#define PNPscsi875 "IBM0018" /* NCR 875 SCSI Controller */ + +/* Sound/Video, Multimedia */ + +#define PNPmm0 "PNPB000" /* Sound Blaster Compatible Sound Device */ +#define PNPmm1 "PNPB001" /* MS Windows Sound System Compat Device */ +#define PNPmmF "IBM000E" /* Crystal CS4231 Audio Device */ +#define PNPv7310 "IBM0015" /* ASCII V7310 Video Capture Device */ +#define PNPmm4232 "IBM0017" /* Crystal CS4232 Audio Device */ +#define PNPpmsyn "IBM001D" /* YMF 289B chip (Yamaha) */ +#define PNPgp4232 "IBM0012" /* Crystal CS4232 Game Port */ +#define PNPmidi4232 "IBM0013" /* Crystal CS4232 MIDI */ + +/* Operator Panel */ +#define PNPopctl "IBM000B" /* Operator's panel */ + +/* Service Processor */ +#define PNPsp "IBM0011" /* IBM Service Processor */ +#define PNPLTsp "IBM001E" /* Lightning/Terlingua Support Processor */ +#define PNPLTmsp "IBM001F" /* Lightning/Terlingua Mini-SP */ + +/* Memory Controller */ +#define PNPmemctl "IBM000A" /* Memory controller */ + +/* Graphics Assist */ +#define PNPg_assist "IBM0014" /* Graphics Assist */ + +/* Miscellaneous Device Controllers */ +#define PNPtablet "IBM0019" /* IBM Tablet Controller */ + +/* PNP Packet Handles */ + +#define S1_Packet 0x0A /* Version resource */ +#define S2_Packet 0x15 /* Logical DEVID (without flags) */ +#define S2_Packet_flags 0x16 /* Logical DEVID (with flags) */ +#define S3_Packet 0x1C /* Compatible device ID */ +#define S4_Packet 0x22 /* IRQ resource (without flags) */ +#define S4_Packet_flags 0x23 /* IRQ resource (with flags) */ +#define S5_Packet 0x2A /* DMA resource */ +#define S6_Packet 0x30 /* Depend funct start (w/o priority) */ +#define S6_Packet_priority 0x31 /* Depend funct start (w/ priority) */ +#define S7_Packet 0x38 /* Depend funct end */ +#define S8_Packet 0x47 /* I/O port resource (w/o fixed loc) */ +#define S9_Packet_fixed 0x4B /* I/O port resource (w/ fixed loc) */ +#define S14_Packet 0x71 /* Vendor defined */ +#define S15_Packet 0x78 /* End of resource (w/o checksum) */ +#define S15_Packet_checksum 0x79 /* End of resource (w/ checksum) */ +#define L1_Packet 0x81 /* Memory range */ +#define L1_Shadow 0x20 /* Memory is shadowable */ +#define L1_32bit_mem 0x18 /* 32-bit memory only */ +#define L1_8_16bit_mem 0x10 /* 8- and 16-bit supported */ +#define L1_Decode_Hi 0x04 /* decode supports high address */ +#define L1_Cache 0x02 /* read cacheable, write-through */ +#define L1_Writeable 0x01 /* Memory is writeable */ +#define L2_Packet 0x82 /* ANSI ID string */ +#define L3_Packet 0x83 /* Unicode ID string */ +#define L4_Packet 0x84 /* Vendor defined */ +#define L5_Packet 0x85 /* Large I/O */ +#define L6_Packet 0x86 /* 32-bit Fixed Loc Mem Range Desc */ +#define END_TAG 0x78 /* End of resource */ +#define DF_START_TAG 0x30 /* Dependent function start */ +#define DF_START_TAG_priority 0x31 /* Dependent function start */ +#define DF_END_TAG 0x38 /* Dependent function end */ +#define SUBOPTIMAL_CONFIGURATION 0x2 /* Priority byte sub optimal config */ + +/* Device Base Type Codes */ + +typedef enum _PnP_BASE_TYPE { + Reserved = 0, + MassStorageDevice = 1, + NetworkInterfaceController = 2, + DisplayController = 3, + MultimediaController = 4, + MemoryController = 5, + BridgeController = 6, + CommunicationsDevice = 7, + SystemPeripheral = 8, + InputDevice = 9, + ServiceProcessor = 0x0A, /* 11/2/95 */ + } PnP_BASE_TYPE; + +/* Device Sub Type Codes */ + +typedef enum _PnP_SUB_TYPE { + SCSIController = 0, + IDEController = 1, + FloppyController = 2, + IPIController = 3, + OtherMassStorageController = 0x80, + + EthernetController = 0, + TokenRingController = 1, + FDDIController = 2, + OtherNetworkController = 0x80, + + VGAController= 0, + SVGAController= 1, + XGAController= 2, + OtherDisplayController = 0x80, + + VideoController = 0, + AudioController = 1, + OtherMultimediaController = 0x80, + + RAM = 0, + FLASH = 1, + OtherMemoryDevice = 0x80, + + HostProcessorBridge = 0, + ISABridge = 1, + EISABridge = 2, + MicroChannelBridge = 3, + PCIBridge = 4, + PCMCIABridge = 5, + VMEBridge = 6, + OtherBridgeDevice = 0x80, + + RS232Device = 0, + ATCompatibleParallelPort = 1, + OtherCommunicationsDevice = 0x80, + + ProgrammableInterruptController = 0, + DMAController = 1, + SystemTimer = 2, + RealTimeClock = 3, + L2Cache = 4, + NVRAM = 5, + PowerManagement = 6, + CMOS = 7, + OperatorPanel = 8, + ServiceProcessorClass1 = 9, + ServiceProcessorClass2 = 0xA, + ServiceProcessorClass3 = 0xB, + GraphicAssist = 0xC, + SystemPlanar = 0xF, /* 10/5/95 */ + OtherSystemPeripheral = 0x80, + + KeyboardController = 0, + Digitizer = 1, + MouseController = 2, + TabletController = 3, /* 10/27/95 */ + OtherInputController = 0x80, + + GeneralMemoryController = 0, + } PnP_SUB_TYPE; + +/* Device Interface Type Codes */ + +typedef enum _PnP_INTERFACE { + General = 0, + GeneralSCSI = 0, + GeneralIDE = 0, + ATACompatible = 1, + + GeneralFloppy = 0, + Compatible765 = 1, + NS398_Floppy = 2, /* NS Super I/O wired to use index + register at port 398 and data + register at port 399 */ + NS26E_Floppy = 3, /* Ports 26E and 26F */ + NS15C_Floppy = 4, /* Ports 15C and 15D */ + NS2E_Floppy = 5, /* Ports 2E and 2F */ + CHRP_Floppy = 6, /* CHRP Floppy in PR*P system */ + + GeneralIPI = 0, + + GeneralEther = 0, + GeneralToken = 0, + GeneralFDDI = 0, + + GeneralVGA = 0, + GeneralSVGA = 0, + GeneralXGA = 0, + + GeneralVideo = 0, + GeneralAudio = 0, + CS4232Audio = 1, /* CS 4232 Plug 'n Play Configured */ + + GeneralRAM = 0, + GeneralFLASH = 0, + PCIMemoryController = 0, /* PCI Config Method */ + RS6KMemoryController = 1, /* RS6K Config Method */ + + GeneralHostBridge = 0, + GeneralISABridge = 0, + GeneralEISABridge = 0, + GeneralMCABridge = 0, + GeneralPCIBridge = 0, + PCIBridgeDirect = 0, + PCIBridgeIndirect = 1, + PCIBridgeRS6K = 2, + GeneralPCMCIABridge = 0, + GeneralVMEBridge = 0, + + GeneralRS232 = 0, + COMx = 1, + Compatible16450 = 2, + Compatible16550 = 3, + NS398SerPort = 4, /* NS Super I/O wired to use index + register at port 398 and data + register at port 399 */ + NS26ESerPort = 5, /* Ports 26E and 26F */ + NS15CSerPort = 6, /* Ports 15C and 15D */ + NS2ESerPort = 7, /* Ports 2E and 2F */ + + GeneralParPort = 0, + LPTx = 1, + NS398ParPort = 2, /* NS Super I/O wired to use index + register at port 398 and data + register at port 399 */ + NS26EParPort = 3, /* Ports 26E and 26F */ + NS15CParPort = 4, /* Ports 15C and 15D */ + NS2EParPort = 5, /* Ports 2E and 2F */ + + GeneralPIC = 0, + ISA_PIC = 1, + EISA_PIC = 2, + MPIC = 3, + RS6K_PIC = 4, + + GeneralDMA = 0, + ISA_DMA = 1, + EISA_DMA = 2, + + GeneralTimer = 0, + ISA_Timer = 1, + EISA_Timer = 2, + GeneralRTC = 0, + ISA_RTC = 1, + + StoreThruOnly = 1, + StoreInEnabled = 2, + RS6KL2Cache = 3, + + IndirectNVRAM = 0, /* Indirectly addressed */ + DirectNVRAM = 1, /* Memory Mapped */ + IndirectNVRAM24 = 2, /* Indirectly addressed - 24 bit */ + + GeneralPowerManagement = 0, + EPOWPowerManagement = 1, + PowerControl = 2, /* d1378 */ + + GeneralCMOS = 0, + + GeneralOPPanel = 0, + HarddiskLight = 1, + CDROMLight = 2, + PowerLight = 3, + KeyLock = 4, + ANDisplay = 5, /* AlphaNumeric Display */ + SystemStatusLED = 6, /* 3 digit 7 segment LED */ + CHRP_SystemStatusLED = 7, /* CHRP LEDs in PR*P system */ + + GeneralServiceProcessor = 0, + + TransferData = 1, + IGMC32 = 2, + IGMC64 = 3, + + GeneralSystemPlanar = 0, /* 10/5/95 */ + + } PnP_INTERFACE; + +/* PnP resources */ + +/* Compressed ASCII is 5 bits per char; 00001=A ... 11010=Z */ + +typedef struct _SERIAL_ID { + unsigned char VendorID0; /* Bit(7)=0 */ + /* Bits(6:2)=1st character in */ + /* compressed ASCII */ + /* Bits(1:0)=2nd character in */ + /* compressed ASCII bits(4:3) */ + unsigned char VendorID1; /* Bits(7:5)=2nd character in */ + /* compressed ASCII bits(2:0) */ + /* Bits(4:0)=3rd character in */ + /* compressed ASCII */ + unsigned char VendorID2; /* Product number - vendor assigned */ + unsigned char VendorID3; /* Product number - vendor assigned */ + +/* Serial number is to provide uniqueness if more than one board of same */ +/* type is in system. Must be "FFFFFFFF" if feature not supported. */ + + unsigned char Serial0; /* Unique serial number bits (7:0) */ + unsigned char Serial1; /* Unique serial number bits (15:8) */ + unsigned char Serial2; /* Unique serial number bits (23:16) */ + unsigned char Serial3; /* Unique serial number bits (31:24) */ + unsigned char Checksum; + } SERIAL_ID; + +typedef enum _PnPItemName { + Unused = 0, + PnPVersion = 1, + LogicalDevice = 2, + CompatibleDevice = 3, + IRQFormat = 4, + DMAFormat = 5, + StartDepFunc = 6, + EndDepFunc = 7, + IOPort = 8, + FixedIOPort = 9, + Res1 = 10, + Res2 = 11, + Res3 = 12, + SmallVendorItem = 14, + EndTag = 15, + MemoryRange = 1, + ANSIIdentifier = 2, + UnicodeIdentifier = 3, + LargeVendorItem = 4, + MemoryRange32 = 5, + MemoryRangeFixed32 = 6, + } PnPItemName; + +/* Define a bunch of access functions for the bits in the tag field */ + +/* Tag type - 0 = small; 1 = large */ +#define tag_type(t) (((t) & 0x80)>>7) +#define set_tag_type(t,v) (t = (t & 0x7f) | ((v)<<7)) + +/* Small item name is 4 bits - one of PnPItemName enum above */ +#define tag_small_item_name(t) (((t) & 0x78)>>3) +#define set_tag_small_item_name(t,v) (t = (t & 0x07) | ((v)<<3)) + +/* Small item count is 3 bits - count of further bytes in packet */ +#define tag_small_count(t) ((t) & 0x07) +#define set_tag_count(t,v) (t = (t & 0x78) | (v)) + +/* Large item name is 7 bits - one of PnPItemName enum above */ +#define tag_large_item_name(t) ((t) & 0x7f) +#define set_tag_large_item_name(t,v) (t = (t | 0x80) | (v)) + +/* a PnP resource is a bunch of contiguous TAG packets ending with an end tag */ + +typedef union _PnP_TAG_PACKET { + struct _S1_Pack{ /* VERSION PACKET */ + unsigned char Tag; /* small tag = 0x0a */ + unsigned char Version[2]; /* PnP version, Vendor version */ + } S1_Pack; + + struct _S2_Pack{ /* LOGICAL DEVICE ID PACKET */ + unsigned char Tag; /* small tag = 0x15 or 0x16 */ + unsigned char DevId[4]; /* Logical device id */ + unsigned char Flags[2]; /* bit(0) boot device; */ + /* bit(7:1) cmd in range x31-x37 */ + /* bit(7:0) cmd in range x28-x3f (opt)*/ + } S2_Pack; + + struct _S3_Pack{ /* COMPATIBLE DEVICE ID PACKET */ + unsigned char Tag; /* small tag = 0x1c */ + unsigned char CompatId[4]; /* Compatible device id */ + } S3_Pack; + + struct _S4_Pack{ /* IRQ PACKET */ + unsigned char Tag; /* small tag = 0x22 or 0x23 */ + unsigned char IRQMask[2]; /* bit(0) is IRQ0, ...; */ + /* bit(0) is IRQ8 ... */ + unsigned char IRQInfo; /* optional; assume bit(0)=1; else */ + /* bit(0) - high true edge sensitive */ + /* bit(1) - low true edge sensitive */ + /* bit(2) - high true level sensitive*/ + /* bit(3) - low true level sensitive */ + /* bit(7:4) - must be 0 */ + } S4_Pack; + + struct _S5_Pack{ /* DMA PACKET */ + unsigned char Tag; /* small tag = 0x2a */ + unsigned char DMAMask; /* bit(0) is channel 0 ... */ + unsigned char DMAInfo; + } S5_Pack; + + struct _S6_Pack{ /* START DEPENDENT FUNCTION PACKET */ + unsigned char Tag; /* small tag = 0x30 or 0x31 */ + unsigned char Priority; /* Optional; if missing then x01; else*/ + /* x00 = best possible */ + /* x01 = acceptible */ + /* x02 = sub-optimal but functional */ + } S6_Pack; + + struct _S7_Pack{ /* END DEPENDENT FUNCTION PACKET */ + unsigned char Tag; /* small tag = 0x38 */ + } S7_Pack; + + struct _S8_Pack{ /* VARIABLE I/O PORT PACKET */ + unsigned char Tag; /* small tag x47 */ + unsigned char IOInfo; /* x0 = decode only bits(9:0); */ +#define ISAAddr16bit 0x01 /* x01 = decode bits(15:0) */ + unsigned char RangeMin[2]; /* Min base address */ + unsigned char RangeMax[2]; /* Max base address */ + unsigned char IOAlign; /* base alignmt, incr in 1B blocks */ + unsigned char IONum; /* number of contiguous I/O ports */ + } S8_Pack; + + struct _S9_Pack{ /* FIXED I/O PORT PACKET */ + unsigned char Tag; /* small tag = 0x4b */ + unsigned char Range[2]; /* base address 10 bits */ + unsigned char IONum; /* number of contiguous I/O ports */ + } S9_Pack; + + struct _S14_Pack{ /* VENDOR DEFINED PACKET */ + unsigned char Tag; /* small tag = 0x7m m = 1-7 */ + union _S14_Data{ + unsigned char Data[7]; /* Vendor defined */ + struct _S14_PPCPack{ /* Pr*p s14 pack */ + unsigned char Type; /* 00=non-IBM */ + unsigned char PPCData[6]; /* Vendor defined */ + } S14_PPCPack; + } S14_Data; + } S14_Pack; + + struct _S15_Pack{ /* END PACKET */ + unsigned char Tag; /* small tag = 0x78 or 0x79 */ + unsigned char Check; /* optional - checksum */ + } S15_Pack; + + struct _L1_Pack{ /* MEMORY RANGE PACKET */ + unsigned char Tag; /* large tag = 0x81 */ + unsigned char Count0; /* x09 */ + unsigned char Count1; /* x00 */ + unsigned char Data[9]; /* a variable array of bytes, */ + /* count in tag */ + } L1_Pack; + + struct _L2_Pack{ /* ANSI ID STRING PACKET */ + unsigned char Tag; /* large tag = 0x82 */ + unsigned char Count0; /* Length of string */ + unsigned char Count1; + unsigned char Identifier[1]; /* a variable array of bytes, */ + /* count in tag */ + } L2_Pack; + + struct _L3_Pack{ /* UNICODE ID STRING PACKET */ + unsigned char Tag; /* large tag = 0x83 */ + unsigned char Count0; /* Length + 2 of string */ + unsigned char Count1; + unsigned char Country0; /* TBD */ + unsigned char Country1; /* TBD */ + unsigned char Identifier[1]; /* a variable array of bytes, */ + /* count in tag */ + } L3_Pack; + + struct _L4_Pack{ /* VENDOR DEFINED PACKET */ + unsigned char Tag; /* large tag = 0x84 */ + unsigned char Count0; + unsigned char Count1; + union _L4_Data{ + unsigned char Data[1]; /* a variable array of bytes, */ + /* count in tag */ + struct _L4_PPCPack{ /* Pr*p L4 packet */ + unsigned char Type; /* 00=non-IBM */ + unsigned char PPCData[1]; /* a variable array of bytes, */ + /* count in tag */ + } L4_PPCPack; + } L4_Data; + } L4_Pack; + + struct _L5_Pack{ + unsigned char Tag; /* large tag = 0x85 */ + unsigned char Count0; /* Count = 17 */ + unsigned char Count1; + unsigned char Data[17]; + } L5_Pack; + + struct _L6_Pack{ + unsigned char Tag; /* large tag = 0x86 */ + unsigned char Count0; /* Count = 9 */ + unsigned char Count1; + unsigned char Data[9]; + } L6_Pack; + + } PnP_TAG_PACKET; + +#endif /* __ASSEMBLY__ */ +#endif /* ndef _PNP_ */ diff --git a/include/ata.h b/include/ata.h new file mode 100644 index 0000000..968b3c4 --- /dev/null +++ b/include/ata.h @@ -0,0 +1,246 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Most of the following information was derived from the document + * "Information Technology - AT Attachment-3 Interface (ATA-3)" + * which can be found at: + * http://www.dt.wdc.com/ata/ata-3/ata3r5v.zip + * ftp://poctok.iae.nsk.su/pub/asm/Documents/IDE/ATA3R5V.ZIP + * ftp://ftp.fee.vutbr.cz/pub/doc/io/ata/ata-3/ata3r5v.zip + */ + +#ifndef _ATA_H +#define _ATA_H + +/* Register addressing depends on the hardware design; for instance, + * 8-bit (register) and 16-bit (data) accesses might use different + * address spaces. This is implemented by the following definitions. + */ + +#define ATA_IO_DATA(x) (CFG_ATA_DATA_OFFSET+(x)) +#define ATA_IO_REG(x) (CFG_ATA_REG_OFFSET +(x)) +#define ATA_IO_ALT(x) (CFG_ATA_ALT_OFFSET +(x)) + +/* + * I/O Register Descriptions + */ +#define ATA_DATA_REG ATA_IO_DATA(0) +#define ATA_ERROR_REG ATA_IO_REG(1) +#define ATA_SECT_CNT ATA_IO_REG(2) +#define ATA_SECT_NUM ATA_IO_REG(3) +#define ATA_CYL_LOW ATA_IO_REG(4) +#define ATA_CYL_HIGH ATA_IO_REG(5) +#define ATA_DEV_HD ATA_IO_REG(6) +#define ATA_COMMAND ATA_IO_REG(7) +#define ATA_STATUS ATA_COMMAND +#define ATA_DEV_CTL ATA_IO_ALT(6) +#define ATA_LBA_LOW ATA_SECT_NUM +#define ATA_LBA_MID ATA_CYL_LOW +#define ATA_LBA_HIGH ATA_CYL_HIGH +#define ATA_LBA_SEL ATA_DEV_CTL + +/* + * Status register bits + */ +#define ATA_STAT_BUSY 0x80 /* Device Busy */ +#define ATA_STAT_READY 0x40 /* Device Ready */ +#define ATA_STAT_FAULT 0x20 /* Device Fault */ +#define ATA_STAT_SEEK 0x10 /* Device Seek Complete */ +#define ATA_STAT_DRQ 0x08 /* Data Request (ready) */ +#define ATA_STAT_CORR 0x04 /* Corrected Data Error */ +#define ATA_STAT_INDEX 0x02 /* Vendor specific */ +#define ATA_STAT_ERR 0x01 /* Error */ + +/* + * Device / Head Register Bits + */ +#define ATA_DEVICE(x) ((x & 1)<<4) +#define ATA_LBA 0xE0 + +/* + * ATA Commands (only mandatory commands listed here) + */ +#define ATA_CMD_READ 0x20 /* Read Sectors (with retries) */ +#define ATA_CMD_READN 0x21 /* Read Sectors ( no retries) */ +#define ATA_CMD_WRITE 0x30 /* Write Sectores (with retries)*/ +#define ATA_CMD_WRITEN 0x31 /* Write Sectors ( no retries)*/ +#define ATA_CMD_VRFY 0x40 /* Read Verify (with retries) */ +#define ATA_CMD_VRFYN 0x41 /* Read verify ( no retries) */ +#define ATA_CMD_SEEK 0x70 /* Seek */ +#define ATA_CMD_DIAG 0x90 /* Execute Device Diagnostic */ +#define ATA_CMD_INIT 0x91 /* Initialize Device Parameters */ +#define ATA_CMD_RD_MULT 0xC4 /* Read Multiple */ +#define ATA_CMD_WR_MULT 0xC5 /* Write Multiple */ +#define ATA_CMD_SETMULT 0xC6 /* Set Multiple Mode */ +#define ATA_CMD_RD_DMA 0xC8 /* Read DMA (with retries) */ +#define ATA_CMD_RD_DMAN 0xC9 /* Read DMS ( no retries) */ +#define ATA_CMD_WR_DMA 0xCA /* Write DMA (with retries) */ +#define ATA_CMD_WR_DMAN 0xCB /* Write DMA ( no retires) */ +#define ATA_CMD_IDENT 0xEC /* Identify Device */ +#define ATA_CMD_SETF 0xEF /* Set Features */ +#define ATA_CMD_CHK_PWR 0xE5 /* Check Power Mode */ + +/* + * 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) +#define ATA_OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) +#define ATA_BAD_R_STAT (ATA_STAT_BUSY | ATA_STAT_ERR) +#define ATA_BAD_W_STAT (ATA_BAD_R_STAT | ATA_STAT_FAULT) +#define ATA_BAD_STAT (ATA_BAD_R_STAT | ATA_STAT_DRQ) +#define ATA_DRIVE_READY (ATA_READY_STAT | ATA_STAT_SEEK) +#define ATA_DATA_READY (ATA_STAT_DRQ) + +#define ATA_BLOCKSIZE 512 /* bytes */ +#define ATA_BLOCKSHIFT 9 /* 2 ^ ATA_BLOCKSIZESHIFT = 512 */ +#define ATA_SECTORWORDS (512 / sizeof(unsigned long)) + +#ifndef ATA_RESET_TIME +#define ATA_RESET_TIME 60 /* spec allows up to 31 seconds */ +#endif + +/* ------------------------------------------------------------------------- */ + +/* + * structure returned by ATA_CMD_IDENT, as per ANSI ATA2 rev.2f spec + */ +typedef struct hd_driveid { + unsigned short config; /* lots of obsolete bit flags */ + unsigned short cyls; /* "physical" cyls */ + unsigned short reserved2; /* reserved (word 2) */ + unsigned short heads; /* "physical" heads */ + unsigned short track_bytes; /* unformatted bytes per track */ + unsigned short sector_bytes; /* unformatted bytes per sector */ + unsigned short sectors; /* "physical" sectors per track */ + unsigned short vendor0; /* vendor unique */ + unsigned short vendor1; /* vendor unique */ + unsigned short vendor2; /* vendor unique */ + unsigned char serial_no[20]; /* 0 = not_specified */ + unsigned short buf_type; + unsigned short buf_size; /* 512 byte increments; 0 = not_specified */ + unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ + unsigned char fw_rev[8]; /* 0 = not_specified */ + unsigned char model[40]; /* 0 = not_specified */ + unsigned char max_multsect; /* 0=not_implemented */ + unsigned char vendor3; /* vendor unique */ + unsigned short dword_io; /* 0=not_implemented; 1=implemented */ + unsigned char vendor4; /* vendor unique */ + unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/ + unsigned short reserved50; /* reserved (word 50) */ + unsigned char vendor5; /* vendor unique */ + unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */ + unsigned char vendor6; /* vendor unique */ + unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */ + unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */ + unsigned short cur_cyls; /* logical cylinders */ + unsigned short cur_heads; /* logical heads */ + unsigned short cur_sectors; /* logical sectors per track */ + unsigned short cur_capacity0; /* logical total sectors on drive */ + unsigned short cur_capacity1; /* (2 words, misaligned int) */ + unsigned char multsect; /* current multiple sector count */ + unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ + unsigned int lba_capacity; /* total number of sectors */ + unsigned short dma_1word; /* single-word dma info */ + unsigned short dma_mword; /* multiple-word dma info */ + unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ + unsigned short eide_dma_min; /* min mword dma cycle time (ns) */ + unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */ + unsigned short eide_pio; /* min cycle time (ns), no IORDY */ + unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */ + unsigned short words69_70[2]; /* reserved words 69-70 */ + unsigned short words71_74[4]; /* reserved words 71-74 */ + unsigned short queue_depth; /* */ + unsigned short words76_79[4]; /* reserved words 76-79 */ + unsigned short major_rev_num; /* */ + unsigned short minor_rev_num; /* */ + unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable 3:PM */ + unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */ + unsigned short cfsse; /* command set-feature supported extensions */ + unsigned short cfs_enable_1; /* command set-feature enabled */ + unsigned short cfs_enable_2; /* command set-feature enabled */ + unsigned short csf_default; /* command set-feature default */ + unsigned short dma_ultra; /* */ + unsigned short word89; /* reserved (word 89) */ + unsigned short word90; /* reserved (word 90) */ + unsigned short CurAPMvalues; /* current APM values */ + unsigned short word92; /* reserved (word 92) */ + unsigned short hw_config; /* hardware config */ + unsigned short words94_125[32];/* reserved words 94-125 */ + unsigned short last_lun; /* reserved (word 126) */ + unsigned short word127; /* reserved (word 127) */ + unsigned short dlf; /* device lock function + * 15:9 reserved + * 8 security level 1:max 0:high + * 7:6 reserved + * 5 enhanced erase + * 4 expire + * 3 frozen + * 2 locked + * 1 en/disabled + * 0 capability + */ + unsigned short csfo; /* current set features options + * 15:4 reserved + * 3 auto reassign + * 2 reverting + * 1 read-look-ahead + * 0 write cache + */ + unsigned short words130_155[26];/* reserved vendor words 130-155 */ + unsigned short word156; + unsigned short words157_159[3];/* reserved vendor words 157-159 */ + unsigned short words160_255[95];/* reserved words 160-255 */ +} hd_driveid_t; + + +/* + * PIO Mode Configuration + * + * See ATA-3 (AT Attachment-3 Interface) documentation, Figure 14 / Table 21 + */ + +typedef struct { + unsigned int t_setup; /* Setup Time in [ns] or clocks */ + unsigned int t_length; /* Length Time in [ns] or clocks */ + unsigned int t_hold; /* Hold Time in [ns] or clocks */ +} +pio_config_t; + +#define IDE_MAX_PIO_MODE 4 /* max suppurted PIO mode */ + +/* ------------------------------------------------------------------------- */ + +#endif /* _ATA_H */ diff --git a/include/commproc.h b/include/commproc.h new file mode 100644 index 0000000..410b96d --- /dev/null +++ b/include/commproc.h @@ -0,0 +1,1593 @@ +/* + * MPC8xx Communication Processor Module. + * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) + * + * This file contains structures and information for the communication + * processor channels. Some CPM control and status is available + * throught the MPC8xx internal memory map. See immap.h for details. + * This file only contains what I need for the moment, not the total + * CPM capabilities. I (or someone else) will add definitions as they + * are needed. -- Dan + * + * On the MBX board, EPPC-Bug loads CPM microcode into the first 512 + * bytes of the DP RAM and relocates the I2C parameter area to the + * IDMA1 space. The remaining DP RAM is available for buffer descriptors + * or other use. + */ +#ifndef __CPM_8XX__ +#define __CPM_8XX__ + +#include <linux/config.h> +#include <asm/8xx_immap.h> + +/* CPM Command register. +*/ +#define CPM_CR_RST ((ushort)0x8000) +#define CPM_CR_OPCODE ((ushort)0x0f00) +#define CPM_CR_CHAN ((ushort)0x00f0) +#define CPM_CR_FLG ((ushort)0x0001) + +/* Some commands (there are more...later) +*/ +#define CPM_CR_INIT_TRX ((ushort)0x0000) +#define CPM_CR_INIT_RX ((ushort)0x0001) +#define CPM_CR_INIT_TX ((ushort)0x0002) +#define CPM_CR_HUNT_MODE ((ushort)0x0003) +#define CPM_CR_STOP_TX ((ushort)0x0004) +#define CPM_CR_RESTART_TX ((ushort)0x0006) +#define CPM_CR_SET_GADDR ((ushort)0x0008) + +/* Channel numbers. +*/ +#define CPM_CR_CH_SCC1 ((ushort)0x0000) +#define CPM_CR_CH_I2C ((ushort)0x0001) /* I2C and IDMA1 */ +#define CPM_CR_CH_SCC2 ((ushort)0x0004) +#define CPM_CR_CH_SPI ((ushort)0x0005) /* SPI / IDMA2 / Timers */ +#define CPM_CR_CH_SCC3 ((ushort)0x0008) +#define CPM_CR_CH_SMC1 ((ushort)0x0009) /* SMC1 / DSP1 */ +#define CPM_CR_CH_SCC4 ((ushort)0x000c) +#define CPM_CR_CH_SMC2 ((ushort)0x000d) /* SMC2 / DSP2 */ + +#define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4)) + +/* + * DPRAM defines and allocation functions + */ + +/* The dual ported RAM is multi-functional. Some areas can be (and are + * being) used for microcode. There is an area that can only be used + * as data ram for buffer descriptors, which is all we use right now. + * Currently the first 512 and last 256 bytes are used for microcode. + */ +#ifdef CFG_ALLOC_DPRAM + +#define CPM_DATAONLY_BASE ((uint)0x0800) +#define CPM_DATAONLY_SIZE ((uint)0x0700) +#define CPM_DP_NOSPACE ((uint)0x7fffffff) + +#else + +#define CPM_SERIAL_BASE 0x0800 +#define CPM_I2C_BASE 0x0820 +#define CPM_SPI_BASE 0x0840 +#define CPM_FEC_BASE 0x0860 +#define CPM_WLKBD_BASE 0x0880 +#define CPM_SCC_BASE 0x0900 +#define CPM_POST_BASE 0x0980 + +#endif + +#define CPM_POST_WORD_ADDR 0x07FC + +#define BD_IIC_START ((uint) 0x0400) /* <- please use CPM_I2C_BASE !! */ + +/* Export the base address of the communication processor registers + * and dual port ram. + */ +extern cpm8xx_t *cpmp; /* Pointer to comm processor */ + +/* Buffer descriptors used by many of the CPM protocols. +*/ +typedef struct cpm_buf_desc { + ushort cbd_sc; /* Status and Control */ + ushort cbd_datlen; /* Data length in buffer */ + uint cbd_bufaddr; /* Buffer address in host memory */ +} cbd_t; + +#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ +#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ +#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ +#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ +#define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame */ +#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */ +#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ +#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ +#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ +#define BD_SC_BR ((ushort)0x0020) /* Break received */ +#define BD_SC_FR ((ushort)0x0010) /* Framing error */ +#define BD_SC_PR ((ushort)0x0008) /* Parity error */ +#define BD_SC_OV ((ushort)0x0002) /* Overrun */ +#define BD_SC_CD ((ushort)0x0001) /* Carrier Detect lost */ + +/* Parameter RAM offsets. +*/ +#define PROFF_SCC1 ((uint)0x0000) +#define PROFF_IIC ((uint)0x0080) +#define PROFF_SCC2 ((uint)0x0100) +#define PROFF_SPI ((uint)0x0180) +#define PROFF_SCC3 ((uint)0x0200) +#define PROFF_SMC1 ((uint)0x0280) +#define PROFF_SCC4 ((uint)0x0300) +#define PROFF_SMC2 ((uint)0x0380) + +/* Define enough so I can at least use the serial port as a UART. + * The MBX uses SMC1 as the host serial port. + */ +typedef struct smc_uart { + ushort smc_rbase; /* Rx Buffer descriptor base address */ + ushort smc_tbase; /* Tx Buffer descriptor base address */ + u_char smc_rfcr; /* Rx function code */ + u_char smc_tfcr; /* Tx function code */ + ushort smc_mrblr; /* Max receive buffer length */ + uint smc_rstate; /* Internal */ + uint smc_idp; /* Internal */ + ushort smc_rbptr; /* Internal */ + ushort smc_ibc; /* Internal */ + uint smc_rxtmp; /* Internal */ + uint smc_tstate; /* Internal */ + uint smc_tdp; /* Internal */ + ushort smc_tbptr; /* Internal */ + ushort smc_tbc; /* Internal */ + uint smc_txtmp; /* Internal */ + ushort smc_maxidl; /* Maximum idle characters */ + ushort smc_tmpidl; /* Temporary idle counter */ + ushort smc_brklen; /* Last received break length */ + ushort smc_brkec; /* rcv'd break condition counter */ + ushort smc_brkcr; /* xmt break count register */ + ushort smc_rmask; /* Temporary bit mask */ +} smc_uart_t; + +/* Function code bits. +*/ +#define SMC_EB ((u_char)0x10) /* Set big endian byte order */ + +/* SMC uart mode register. +*/ +#define SMCMR_REN ((ushort)0x0001) +#define SMCMR_TEN ((ushort)0x0002) +#define SMCMR_DM ((ushort)0x000c) +#define SMCMR_SM_GCI ((ushort)0x0000) +#define SMCMR_SM_UART ((ushort)0x0020) +#define SMCMR_SM_TRANS ((ushort)0x0030) +#define SMCMR_SM_MASK ((ushort)0x0030) +#define SMCMR_PM_EVEN ((ushort)0x0100) /* Even parity, else odd */ +#define SMCMR_REVD SMCMR_PM_EVEN +#define SMCMR_PEN ((ushort)0x0200) /* Parity enable */ +#define SMCMR_BS SMCMR_PEN +#define SMCMR_SL ((ushort)0x0400) /* Two stops, else one */ +#define SMCR_CLEN_MASK ((ushort)0x7800) /* Character length */ +#define smcr_mk_clen(C) (((C) << 11) & SMCR_CLEN_MASK) + +/* SMC2 as Centronics parallel printer. It is half duplex, in that + * it can only receive or transmit. The parameter ram values for + * each direction are either unique or properly overlap, so we can + * include them in one structure. + */ +typedef struct smc_centronics { + ushort scent_rbase; + ushort scent_tbase; + u_char scent_cfcr; + u_char scent_smask; + ushort scent_mrblr; + uint scent_rstate; + uint scent_r_ptr; + ushort scent_rbptr; + ushort scent_r_cnt; + uint scent_rtemp; + uint scent_tstate; + uint scent_t_ptr; + ushort scent_tbptr; + ushort scent_t_cnt; + uint scent_ttemp; + ushort scent_max_sl; + ushort scent_sl_cnt; + ushort scent_character1; + ushort scent_character2; + ushort scent_character3; + ushort scent_character4; + ushort scent_character5; + ushort scent_character6; + ushort scent_character7; + ushort scent_character8; + ushort scent_rccm; + ushort scent_rccr; +} smc_cent_t; + +/* Centronics Status Mask Register. +*/ +#define SMC_CENT_F ((u_char)0x08) +#define SMC_CENT_PE ((u_char)0x04) +#define SMC_CENT_S ((u_char)0x02) + +/* SMC Event and Mask register. +*/ +#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */ +#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */ +#define SMCM_TXE ((unsigned char)0x10) /* When in Transparent Mode */ +#define SMCM_BSY ((unsigned char)0x04) +#define SMCM_TX ((unsigned char)0x02) +#define SMCM_RX ((unsigned char)0x01) + +/* Baud rate generators. +*/ +#define CPM_BRG_RST ((uint)0x00020000) +#define CPM_BRG_EN ((uint)0x00010000) +#define CPM_BRG_EXTC_INT ((uint)0x00000000) +#define CPM_BRG_EXTC_CLK2 ((uint)0x00004000) +#define CPM_BRG_EXTC_CLK6 ((uint)0x00008000) +#define CPM_BRG_ATB ((uint)0x00002000) +#define CPM_BRG_CD_MASK ((uint)0x00001ffe) +#define CPM_BRG_DIV16 ((uint)0x00000001) + +/* SI Clock Route Register +*/ +#define SICR_RCLK_SCC1_BRG1 ((uint)0x00000000) +#define SICR_TCLK_SCC1_BRG1 ((uint)0x00000000) +#define SICR_RCLK_SCC2_BRG2 ((uint)0x00000800) +#define SICR_TCLK_SCC2_BRG2 ((uint)0x00000100) +#define SICR_RCLK_SCC3_BRG3 ((uint)0x00100000) +#define SICR_TCLK_SCC3_BRG3 ((uint)0x00020000) +#define SICR_RCLK_SCC4_BRG4 ((uint)0x18000000) +#define SICR_TCLK_SCC4_BRG4 ((uint)0x03000000) + +/* SCCs. +*/ +#define SCC_GSMRH_IRP ((uint)0x00040000) +#define SCC_GSMRH_GDE ((uint)0x00010000) +#define SCC_GSMRH_TCRC_CCITT ((uint)0x00008000) +#define SCC_GSMRH_TCRC_BISYNC ((uint)0x00004000) +#define SCC_GSMRH_TCRC_HDLC ((uint)0x00000000) +#define SCC_GSMRH_REVD ((uint)0x00002000) +#define SCC_GSMRH_TRX ((uint)0x00001000) +#define SCC_GSMRH_TTX ((uint)0x00000800) +#define SCC_GSMRH_CDP ((uint)0x00000400) +#define SCC_GSMRH_CTSP ((uint)0x00000200) +#define SCC_GSMRH_CDS ((uint)0x00000100) +#define SCC_GSMRH_CTSS ((uint)0x00000080) +#define SCC_GSMRH_TFL ((uint)0x00000040) +#define SCC_GSMRH_RFW ((uint)0x00000020) +#define SCC_GSMRH_TXSY ((uint)0x00000010) +#define SCC_GSMRH_SYNL16 ((uint)0x0000000c) +#define SCC_GSMRH_SYNL8 ((uint)0x00000008) +#define SCC_GSMRH_SYNL4 ((uint)0x00000004) +#define SCC_GSMRH_RTSM ((uint)0x00000002) +#define SCC_GSMRH_RSYN ((uint)0x00000001) + +#define SCC_GSMRL_SIR ((uint)0x80000000) /* SCC2 only */ +#define SCC_GSMRL_EDGE_NONE ((uint)0x60000000) +#define SCC_GSMRL_EDGE_NEG ((uint)0x40000000) +#define SCC_GSMRL_EDGE_POS ((uint)0x20000000) +#define SCC_GSMRL_EDGE_BOTH ((uint)0x00000000) +#define SCC_GSMRL_TCI ((uint)0x10000000) +#define SCC_GSMRL_TSNC_3 ((uint)0x0c000000) +#define SCC_GSMRL_TSNC_4 ((uint)0x08000000) +#define SCC_GSMRL_TSNC_14 ((uint)0x04000000) +#define SCC_GSMRL_TSNC_INF ((uint)0x00000000) +#define SCC_GSMRL_RINV ((uint)0x02000000) +#define SCC_GSMRL_TINV ((uint)0x01000000) +#define SCC_GSMRL_TPL_128 ((uint)0x00c00000) +#define SCC_GSMRL_TPL_64 ((uint)0x00a00000) +#define SCC_GSMRL_TPL_48 ((uint)0x00800000) +#define SCC_GSMRL_TPL_32 ((uint)0x00600000) +#define SCC_GSMRL_TPL_16 ((uint)0x00400000) +#define SCC_GSMRL_TPL_8 ((uint)0x00200000) +#define SCC_GSMRL_TPL_NONE ((uint)0x00000000) +#define SCC_GSMRL_TPP_ALL1 ((uint)0x00180000) +#define SCC_GSMRL_TPP_01 ((uint)0x00100000) +#define SCC_GSMRL_TPP_10 ((uint)0x00080000) +#define SCC_GSMRL_TPP_ZEROS ((uint)0x00000000) +#define SCC_GSMRL_TEND ((uint)0x00040000) +#define SCC_GSMRL_TDCR_32 ((uint)0x00030000) +#define SCC_GSMRL_TDCR_16 ((uint)0x00020000) +#define SCC_GSMRL_TDCR_8 ((uint)0x00010000) +#define SCC_GSMRL_TDCR_1 ((uint)0x00000000) +#define SCC_GSMRL_RDCR_32 ((uint)0x0000c000) +#define SCC_GSMRL_RDCR_16 ((uint)0x00008000) +#define SCC_GSMRL_RDCR_8 ((uint)0x00004000) +#define SCC_GSMRL_RDCR_1 ((uint)0x00000000) +#define SCC_GSMRL_RENC_DFMAN ((uint)0x00003000) +#define SCC_GSMRL_RENC_MANCH ((uint)0x00002000) +#define SCC_GSMRL_RENC_FM0 ((uint)0x00001000) +#define SCC_GSMRL_RENC_NRZI ((uint)0x00000800) +#define SCC_GSMRL_RENC_NRZ ((uint)0x00000000) +#define SCC_GSMRL_TENC_DFMAN ((uint)0x00000600) +#define SCC_GSMRL_TENC_MANCH ((uint)0x00000400) +#define SCC_GSMRL_TENC_FM0 ((uint)0x00000200) +#define SCC_GSMRL_TENC_NRZI ((uint)0x00000100) +#define SCC_GSMRL_TENC_NRZ ((uint)0x00000000) +#define SCC_GSMRL_DIAG_LE ((uint)0x000000c0) /* Loop and echo */ +#define SCC_GSMRL_DIAG_ECHO ((uint)0x00000080) +#define SCC_GSMRL_DIAG_LOOP ((uint)0x00000040) +#define SCC_GSMRL_DIAG_NORM ((uint)0x00000000) +#define SCC_GSMRL_ENR ((uint)0x00000020) +#define SCC_GSMRL_ENT ((uint)0x00000010) +#define SCC_GSMRL_MODE_ENET ((uint)0x0000000c) +#define SCC_GSMRL_MODE_DDCMP ((uint)0x00000009) +#define SCC_GSMRL_MODE_BISYNC ((uint)0x00000008) +#define SCC_GSMRL_MODE_V14 ((uint)0x00000007) +#define SCC_GSMRL_MODE_AHDLC ((uint)0x00000006) +#define SCC_GSMRL_MODE_PROFIBUS ((uint)0x00000005) +#define SCC_GSMRL_MODE_UART ((uint)0x00000004) +#define SCC_GSMRL_MODE_SS7 ((uint)0x00000003) +#define SCC_GSMRL_MODE_ATALK ((uint)0x00000002) +#define SCC_GSMRL_MODE_HDLC ((uint)0x00000000) + +#define SCC_TODR_TOD ((ushort)0x8000) + +/* SCC Event and Mask register. +*/ +#define SCCM_TXE ((unsigned char)0x10) +#define SCCM_BSY ((unsigned char)0x04) +#define SCCM_TX ((unsigned char)0x02) +#define SCCM_RX ((unsigned char)0x01) + +typedef struct scc_param { + ushort scc_rbase; /* Rx Buffer descriptor base address */ + ushort scc_tbase; /* Tx Buffer descriptor base address */ + u_char scc_rfcr; /* Rx function code */ + u_char scc_tfcr; /* Tx function code */ + ushort scc_mrblr; /* Max receive buffer length */ + uint scc_rstate; /* Internal */ + uint scc_idp; /* Internal */ + ushort scc_rbptr; /* Internal */ + ushort scc_ibc; /* Internal */ + uint scc_rxtmp; /* Internal */ + uint scc_tstate; /* Internal */ + uint scc_tdp; /* Internal */ + ushort scc_tbptr; /* Internal */ + ushort scc_tbc; /* Internal */ + uint scc_txtmp; /* Internal */ + uint scc_rcrc; /* Internal */ + uint scc_tcrc; /* Internal */ +} sccp_t; + +/* Function code bits. +*/ +#define SCC_EB ((u_char)0x10) /* Set big endian byte order */ + +/* CPM Ethernet through SCCx. + */ +typedef struct scc_enet { + sccp_t sen_genscc; + uint sen_cpres; /* Preset CRC */ + uint sen_cmask; /* Constant mask for CRC */ + uint sen_crcec; /* CRC Error counter */ + uint sen_alec; /* alignment error counter */ + uint sen_disfc; /* discard frame counter */ + ushort sen_pads; /* Tx short frame pad character */ + ushort sen_retlim; /* Retry limit threshold */ + ushort sen_retcnt; /* Retry limit counter */ + ushort sen_maxflr; /* maximum frame length register */ + ushort sen_minflr; /* minimum frame length register */ + ushort sen_maxd1; /* maximum DMA1 length */ + ushort sen_maxd2; /* maximum DMA2 length */ + ushort sen_maxd; /* Rx max DMA */ + ushort sen_dmacnt; /* Rx DMA counter */ + ushort sen_maxb; /* Max BD byte count */ + ushort sen_gaddr1; /* Group address filter */ + ushort sen_gaddr2; + ushort sen_gaddr3; + ushort sen_gaddr4; + uint sen_tbuf0data0; /* Save area 0 - current frame */ + uint sen_tbuf0data1; /* Save area 1 - current frame */ + uint sen_tbuf0rba; /* Internal */ + uint sen_tbuf0crc; /* Internal */ + ushort sen_tbuf0bcnt; /* Internal */ + ushort sen_paddrh; /* physical address (MSB) */ + ushort sen_paddrm; + ushort sen_paddrl; /* physical address (LSB) */ + ushort sen_pper; /* persistence */ + ushort sen_rfbdptr; /* Rx first BD pointer */ + ushort sen_tfbdptr; /* Tx first BD pointer */ + ushort sen_tlbdptr; /* Tx last BD pointer */ + uint sen_tbuf1data0; /* Save area 0 - current frame */ + uint sen_tbuf1data1; /* Save area 1 - current frame */ + uint sen_tbuf1rba; /* Internal */ + uint sen_tbuf1crc; /* Internal */ + ushort sen_tbuf1bcnt; /* Internal */ + ushort sen_txlen; /* Tx Frame length counter */ + ushort sen_iaddr1; /* Individual address filter */ + ushort sen_iaddr2; + ushort sen_iaddr3; + ushort sen_iaddr4; + ushort sen_boffcnt; /* Backoff counter */ + + /* NOTE: Some versions of the manual have the following items + * incorrectly documented. Below is the proper order. + */ + ushort sen_taddrh; /* temp address (MSB) */ + ushort sen_taddrm; + ushort sen_taddrl; /* temp address (LSB) */ +} scc_enet_t; + +/********************************************************************** + * + * Board specific configuration settings. + * + * Please note that we use the presence of a #define SCC_ENET and/or + * #define FEC_ENET to enable the SCC resp. FEC ethernet drivers. + **********************************************************************/ + + +/*** ADS *************************************************************/ + +#if defined(CONFIG_MPC860) && defined(CONFIG_ADS) +/* This ENET stuff is for the MPC860ADS with ethernet on SCC1. + */ + +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 + +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) + +#define PB_ENET_TENA ((uint)0x00001000) + +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002c) + +/* 68160 PHY control */ + +#define PC_ENET_ETHLOOP ((ushort)0x0800) +#define PC_ENET_TPFLDL ((ushort)0x0400) +#define PC_ENET_TPSQEL ((ushort)0x0200) + +#endif /* MPC860ADS */ + +/*** AMX860 **********************************************/ + +#if defined(CONFIG_AMX860) + +/* This ENET stuff is for the AMX860 with ethernet on SCC1. + */ + +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 + +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0400) +#define PA_ENET_RCLK ((ushort)0x0800) + +#define PB_ENET_TENA ((uint)0x00001000) + +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000003e) + +/* 68160 PHY control */ + +#define PB_ENET_ETHLOOP ((uint)0x00020000) +#define PB_ENET_TPFLDL ((uint)0x00010000) +#define PB_ENET_TPSQEL ((uint)0x00008000) +#define PD_ENET_ETH_EN ((ushort)0x0004) + +#endif /* CONFIG_AMX860 */ + +/*** BSEIP **********************************************************/ + +#ifdef CONFIG_BSEIP +/* This ENET stuff is for the MPC823 with ethernet on SCC2. + * This is unique to the BSE ip-Engine board. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +/* BSE uses port B and C bits for PHY control also. +*/ +#define PB_BSE_POWERUP ((uint)0x00000004) +#define PB_BSE_FDXDIS ((uint)0x00008000) +#define PC_BSE_LOOPBACK ((ushort)0x0800) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002c00) +#endif /* CONFIG_BSEIP */ + +/*** BSEIP **********************************************************/ + +#ifdef CONFIG_FLAGADM +/* Enet configuration for the FLAGADM */ +/* Enet on SCC2 */ + +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0400) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00003400) +#endif /* CONFIG_FLAGADM */ + +/*** C2MON **********************************************************/ + +#ifdef CONFIG_C2MON + +# ifndef CONFIG_FEC_ENET /* use SCC for 10Mbps Ethernet */ +# error "Ethernet on SCC not supported on C2MON Board!" +# else /* Use FEC for Fast Ethernet */ + +#undef SCC_ENET +#define FEC_ENET + +#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */ +#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */ +#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */ +#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */ +#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */ +#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */ +#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */ +#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */ +#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */ +#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */ +#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */ +#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */ +#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */ + +#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */ + +# endif /* CONFIG_FEC_ENET */ +#endif /* CONFIG_C2MON */ + +/*********************************************************************/ + + +/*** CCM and PCU E ***********************************************/ + +/* The PCU E and CCM use the FEC on a MPC860T for Ethernet */ + +#if defined (CONFIG_PCU_E) || defined(CONFIG_CCM) + +#define FEC_ENET /* use FEC for EThernet */ +#undef SCC_ENET + +#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */ +#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */ +#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */ +#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */ +#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */ +#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */ +#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */ +#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */ +#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */ +#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */ +#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */ +#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */ +#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */ + +#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */ + +#endif /* CONFIG_PCU_E, CONFIG_CCM */ + +/*** ESTEEM 192E **************************************************/ +#ifdef CONFIG_ESTEEM192E +/* ESTEEM192E + * This ENET stuff is for the MPC850 with ethernet on SCC2. This + * is very similar to the RPX-Lite configuration. + * Note TENA , LOOPBACK , FDPLEX_DIS on Port B. + */ + +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 + +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0200) +#define PA_ENET_RCLK ((ushort)0x0800) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00003d00) + +#define PB_ENET_LOOPBACK ((uint)0x00004000) +#define PB_ENET_FDPLEX_DIS ((uint)0x00008000) + +#endif + +/*** FADS823 ********************************************************/ + +#if defined(CONFIG_MPC823FADS) && defined(CONFIG_FADS) +/* This ENET stuff is for the MPC823FADS with ethernet on SCC2. + */ +#ifdef CONFIG_SCC2_ENET +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define CPMVEC_ENET CPMVEC_SCC2 +#endif + +#ifdef CONFIG_SCC1_ENET +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 +#define CPMVEC_ENET CPMVEC_SCC1 +#endif + +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0400) +#define PA_ENET_RCLK ((ushort)0x0200) + +#define PB_ENET_TENA ((uint)0x00002000) + +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002e00) + +#endif /* CONFIG_FADS823FADS */ + +/*** FADS850SAR ********************************************************/ + +#if defined(CONFIG_MPC850SAR) && defined(CONFIG_FADS) +/* This ENET stuff is for the MPC850SAR with ethernet on SCC2. Some of + * this may be unique to the FADS850SAR configuration. + * Note TENA is on Port B. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0800) /* PA 4 */ +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002f00) /* RCLK-CLK2, TCLK-CLK4 */ +#endif /* CONFIG_FADS850SAR */ + +/*** FADS860T********************************************************/ + +#if defined(CONFIG_MPC860T) && defined(CONFIG_FADS) +/* This ENET stuff is for the MPC860TFADS with ethernet on SCC1. + */ + +#ifdef CONFIG_SCC1_ENET +#define SCC_ENET 0 +#endif /* CONFIG_SCC1_ETHERNET */ +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 + +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) + +#define PB_ENET_TENA ((uint)0x00001000) + +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002c) + +/* This ENET stuff is for the MPC860TFADS with ethernet on FEC. + */ + +#ifdef CONFIG_FEC_ENET +#define FEC_ENET /* use FEC for EThernet */ +#endif /* CONFIG_FEC_ETHERNET */ + +#endif /* CONFIG_FADS860T */ + +/*** FPS850L *********************************************************/ + +#ifdef CONFIG_FPS850L +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */ +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002600) +#endif /* CONFIG_FPS850L */ + +/*** GEN860T **********************************************************/ +#if defined(CONFIG_GEN860T) +#undef SCC_ENET +#define FEC_ENET + +#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */ +#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */ +#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */ +#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */ +#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */ +#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */ +#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */ +#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */ +#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */ +#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */ +#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */ +#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */ +#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */ +#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3-15 */ +#endif /* CONFIG_GEN860T */ + +/*** GENIETV ********************************************************/ + +#if defined(CONFIG_GENIETV) +/* Ethernet is only on SCC2 */ + +#define CONFIG_SCC2_ENET +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define CPMVEC_ENET CPMVEC_SCC2 + +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ + +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002e00) + +#endif /* CONFIG_GENIETV */ + +/*** GTH ******************************************************/ + +#ifdef CONFIG_GTH +#ifdef CONFIG_FEC_ENET +#define FEC_ENET /* use FEC for EThernet */ +#endif /* CONFIG_FEC_ETHERNET */ + +/* This ENET stuff is for GTH 10 Mbit ( SCC ) */ +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 + +#define PA_ENET_RXD ((ushort)0x0001) /* PA15 */ +#define PA_ENET_TXD ((ushort)0x0002) /* PA14 */ +#define PA_ENET_TCLK ((ushort)0x0800) /* PA4 */ +#define PA_ENET_RCLK ((ushort)0x0400) /* PA5 */ + +#define PB_ENET_TENA ((uint)0x00001000) /* PB19 */ + +#define PC_ENET_CLSN ((ushort)0x0010) /* PC11 */ +#define PC_ENET_RENA ((ushort)0x0020) /* PC10 */ + +/* NOTE. This is reset for 10Mbit port only */ +#define PC_ENET_RESET ((ushort)0x0100) /* PC 7 */ + +#define SICR_ENET_MASK ((uint)0x000000ff) + +/* TCLK PA4 -->CLK4, RCLK PA5 -->CLK3 */ +#define SICR_ENET_CLKRT ((uint)0x00000037) + +#endif /* CONFIG_GTH */ + +/*** HERMES-PRO ******************************************************/ + +/* The HERMES-PRO uses the FEC on a MPC860T for Ethernet */ + +#ifdef CONFIG_HERMES + +#define FEC_ENET /* use FEC for EThernet */ +#undef SCC_ENET + + +#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */ +#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */ +#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */ +#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */ +#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */ +#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */ +#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */ +#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */ +#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */ +#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */ +#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */ +#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */ +#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */ + +#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */ + +#endif /* CONFIG_HERMES */ + +/*** IAD210 **********************************************************/ + +/* The IAD210 uses the FEC on a MPC860P for Ethernet */ + +#if defined(CONFIG_IAD210) + +# define FEC_ENET /* use FEC for Ethernet */ +# undef SCC_ENET + +# define PD_MII_TXD1 ((ushort) 0x1000 ) /* PD 3 */ +# define PD_MII_TXD2 ((ushort) 0x0800 ) /* PD 4 */ +# define PD_MII_TXD3 ((ushort) 0x0400 ) /* PD 5 */ +# define PD_MII_RX_DV ((ushort) 0x0200 ) /* PD 6 */ +# define PD_MII_RX_ERR ((ushort) 0x0100 ) /* PD 7 */ +# define PD_MII_RX_CLK ((ushort) 0x0080 ) /* PD 8 */ +# define PD_MII_TXD0 ((ushort) 0x0040 ) /* PD 9 */ +# define PD_MII_RXD0 ((ushort) 0x0020 ) /* PD 10 */ +# define PD_MII_TX_ERR ((ushort) 0x0010 ) /* PD 11 */ +# define PD_MII_MDC ((ushort) 0x0008 ) /* PD 12 */ +# define PD_MII_RXD1 ((ushort) 0x0004 ) /* PD 13 */ +# define PD_MII_RXD2 ((ushort) 0x0002 ) /* PD 14 */ +# define PD_MII_RXD3 ((ushort) 0x0001 ) /* PD 15 */ + +# define PD_MII_MASK ((ushort) 0x1FFF ) /* PD 3...15 */ + +#endif /* CONFIG_IAD210 */ + +/*** ICU862 **********************************************************/ + +#if defined(CONFIG_ICU862) + +#ifdef CONFIG_FEC_ENET +#define FEC_ENET /* use FEC for EThernet */ +#endif /* CONFIG_FEC_ETHERNET */ + +#endif /* CONFIG_ICU862 */ + +/*** IP860 **********************************************************/ + +#if defined(CONFIG_IP860) +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 +#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */ +#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0100) /* PA 7 */ + +#define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */ +#define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */ +#define PC_ENET_RENA ((ushort)0x0020) /* PC 10 */ + +#define PB_ENET_RESET (uint)0x00000008 /* PB 28 */ +#define PB_ENET_JABD (uint)0x00000004 /* PB 29 */ + +/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002C) +#endif /* CONFIG_IP860 */ + +/*** IVMS8 **********************************************************/ + +/* The IVMS8 uses the FEC on a MPC860T for Ethernet */ + +#if defined(CONFIG_IVMS8) || defined(CONFIG_IVML24) + +#define FEC_ENET /* use FEC for EThernet */ +#undef SCC_ENET + +#define PB_ENET_POWER ((uint)0x00010000) /* PB 15 */ + +#define PC_ENET_RESET ((ushort)0x0010) /* PC 11 */ + +#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */ +#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */ +#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */ +#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */ +#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */ +#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */ +#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */ +#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */ +#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */ +#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */ +#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */ +#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */ +#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */ + +#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */ + +#endif /* CONFIG_IVMS8, CONFIG_IVML24 */ + +/*** LANTEC *********************************************************/ + +#if defined(CONFIG_LANTEC) && CONFIG_LANTEC >= 2 +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC2 use. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_LBK ((ushort)0x0010) /* PC 11 */ +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000FF00) +#define SICR_ENET_CLKRT ((uint)0x00002E00) +#endif /* CONFIG_LANTEC v2 */ + +/*** LWMON **********************************************************/ + +#if defined(CONFIG_LWMON) && !defined(CONFIG_8xx_CONS_SCC2) +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC2 use. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0800) /* PA 4 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK4) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00003E00) +#endif /* CONFIG_LWMON */ + +/*** NX823 ***********************************************/ + +#if defined(CONFIG_NX823) +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0800) /* PA 4 */ + +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002f00) + +#endif /* CONFIG_NX823 */ + +/*** MBX ************************************************************/ + +#ifdef CONFIG_MBX +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. The TCLK and RCLK seem unique + * to the MBX860 board. Any two of the four available clocks could be + * used, and the MPC860 cookbook manual has an example using different + * clock pins. + */ +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0200) +#define PA_ENET_RCLK ((ushort)0x0800) +#define PC_ENET_TENA ((ushort)0x0001) +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000003d) +#endif /* CONFIG_MBX */ + +/*** MHPC ********************************************************/ + +#if defined(CONFIG_MHPC) +/* This ENET stuff is for the MHPC with ethernet on SCC2. + * Note TENA is on Port B. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002e00) /* RCLK-CLK2, TCLK-CLK3 */ +#endif /* CONFIG_MHPC */ + +/*** RPXCLASSIC *****************************************************/ + +#ifdef CONFIG_RPXCLASSIC + +#ifdef CONFIG_FEC_ENET + +# define FEC_ENET /* use FEC for EThernet */ +# undef SCC_ENET + +#else /* ! CONFIG_FEC_ENET */ + +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0200) +#define PA_ENET_RCLK ((ushort)0x0800) +#define PB_ENET_TENA ((uint)0x00001000) +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000003d) + +#endif /* CONFIG_FEC_ENET */ + +#endif /* CONFIG_RPXCLASSIC */ + +/*** RPXLITE ********************************************************/ + +#ifdef CONFIG_RPXLITE +/* This ENET stuff is for the MPC850 with ethernet on SCC2. Some of + * this may be unique to the RPX-Lite configuration. + * Note TENA is on Port B. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0200) +#define PA_ENET_RCLK ((ushort)0x0800) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00003d00) +#endif /* CONFIG_RPXLITE */ + +/*** SM850 *********************************************************/ + +/* The SM850 Service Module uses SCC2 for IrDA and SCC3 for Ethernet */ + +#ifdef CONFIG_SM850 +#define PROFF_ENET PROFF_SCC3 /* Ethernet on SCC3 */ +#define CPM_CR_ENET CPM_CR_CH_SCC3 +#define SCC_ENET 2 +#define PB_ENET_RXD ((uint)0x00000004) /* PB 29 */ +#define PB_ENET_TXD ((uint)0x00000002) /* PB 30 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PC_ENET_LBK ((ushort)0x0008) /* PC 12 */ +#define PC_ENET_TENA ((ushort)0x0004) /* PC 13 */ + +#define PC_ENET_RENA ((ushort)0x0800) /* PC 4 */ +#define PC_ENET_CLSN ((ushort)0x0400) /* PC 5 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero. + */ +#define SICR_ENET_MASK ((uint)0x00FF0000) +#define SICR_ENET_CLKRT ((uint)0x00260000) +#endif /* CONFIG_SM850 */ + +/*** SPD823TS ******************************************************/ + +#ifdef CONFIG_SPD823TS +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC2 use. + */ +#define PROFF_ENET PROFF_SCC2 /* Ethernet on SCC2 */ +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_MDC ((ushort)0x0001) /* PA 15 !!! */ +#define PA_ENET_MDIO ((ushort)0x0002) /* PA 14 !!! */ +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ +#define PC_ENET_RESET ((ushort)0x0100) /* PC 7 !!! */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002E00) +#endif /* CONFIG_SPD823TS */ + +/*** SXNI855T ******************************************************/ + +#if defined(CONFIG_SXNI855T) + +#ifdef CONFIG_FEC_ENET +#define FEC_ENET /* use FEC for Ethernet */ +#endif /* CONFIG_FEC_ETHERNET */ + +#endif /* CONFIG_SXNI855T */ + +/*** MVS1, TQM823L, TQM850L, ETX094, R360MPI ***********************/ + +#if (defined(CONFIG_MVS) && CONFIG_MVS < 2) || \ + defined(CONFIG_R360MPI) || \ + defined(CONFIG_TQM823L) || \ + defined(CONFIG_TQM850L) || \ + defined(CONFIG_ETX094) || \ + defined(CONFIG_RRVISION)|| \ + (defined(CONFIG_LANTEC) && CONFIG_LANTEC < 2) +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC2 use. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ +#if defined(CONFIG_R360MPI) +#define PC_ENET_LBK ((ushort)0x0008) /* PC 12 */ +#endif /* CONFIG_R360MPI */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002600) +#endif /* CONFIG_MVS v1, CONFIG_TQM823L, CONFIG_TQM850L, etc. */ + +/*** TQM860L, TQM855L ************************************************/ + +#if (defined(CONFIG_TQM860L) || defined(CONFIG_TQM855L)) + +# ifdef CONFIG_SCC1_ENET /* use SCC for 10Mbps Ethernet */ + +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + */ +#define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 +#define SCC_ENET 0 +#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */ +#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */ +#define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */ +#define PC_ENET_RENA ((ushort)0x0020) /* PC 10 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x00000026) + +# endif /* CONFIG_SCC1_ENET */ + +# ifdef CONFIG_FEC_ENET /* Use FEC for Fast Ethernet */ + +#define FEC_ENET + +#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */ +#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */ +#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */ +#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */ +#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */ +#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */ +#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */ +#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */ +#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */ +#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */ +#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */ +#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */ +#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */ + +#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */ + +# endif /* CONFIG_FEC_ENET */ +#endif /* CONFIG_TQM860L, CONFIG_TQM855L */ + +#if defined(CONFIG_NETVIA) +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC2 use. + */ +#define PROFF_ENET PROFF_SCC2 +#define CPM_CR_ENET CPM_CR_CH_SCC2 +#define SCC_ENET 1 +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */ +#define PA_ENET_TCLK ((ushort)0x0800) /* PA 4 */ + +#define PB_ENET_PDN ((ushort)0x4000) /* PB 17 */ +#define PB_ENET_TENA ((ushort)0x2000) /* PB 18 */ + +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002f00) + +#endif /* CONFIG_NETVIA */ + +/*********************************************************************/ + +/* SCC Event register as used by Ethernet. +*/ +#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */ +#define SCCE_ENET_TXE ((ushort)0x0010) /* Transmit Error */ +#define SCCE_ENET_RXF ((ushort)0x0008) /* Full frame received */ +#define SCCE_ENET_BSY ((ushort)0x0004) /* All incoming buffers full */ +#define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */ +#define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */ + +/* SCC Mode Register (PSMR) as used by Ethernet. +*/ +#define SCC_PSMR_HBC ((ushort)0x8000) /* Enable heartbeat */ +#define SCC_PSMR_FC ((ushort)0x4000) /* Force collision */ +#define SCC_PSMR_RSH ((ushort)0x2000) /* Receive short frames */ +#define SCC_PSMR_IAM ((ushort)0x1000) /* Check individual hash */ +#define SCC_PSMR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */ +#define SCC_PSMR_PRO ((ushort)0x0200) /* Promiscuous mode */ +#define SCC_PSMR_BRO ((ushort)0x0100) /* Catch broadcast pkts */ +#define SCC_PSMR_SBT ((ushort)0x0080) /* Special backoff timer */ +#define SCC_PSMR_LPB ((ushort)0x0040) /* Set Loopback mode */ +#define SCC_PSMR_SIP ((ushort)0x0020) /* Sample Input Pins */ +#define SCC_PSMR_LCW ((ushort)0x0010) /* Late collision window */ +#define SCC_PSMR_NIB22 ((ushort)0x000a) /* Start frame search */ +#define SCC_PSMR_FDE ((ushort)0x0001) /* Full duplex enable */ + +/* Buffer descriptor control/status used by Ethernet receive. +*/ +#define BD_ENET_RX_EMPTY ((ushort)0x8000) +#define BD_ENET_RX_WRAP ((ushort)0x2000) +#define BD_ENET_RX_INTR ((ushort)0x1000) +#define BD_ENET_RX_LAST ((ushort)0x0800) +#define BD_ENET_RX_FIRST ((ushort)0x0400) +#define BD_ENET_RX_MISS ((ushort)0x0100) +#define BD_ENET_RX_LG ((ushort)0x0020) +#define BD_ENET_RX_NO ((ushort)0x0010) +#define BD_ENET_RX_SH ((ushort)0x0008) +#define BD_ENET_RX_CR ((ushort)0x0004) +#define BD_ENET_RX_OV ((ushort)0x0002) +#define BD_ENET_RX_CL ((ushort)0x0001) +#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */ + +/* Buffer descriptor control/status used by Ethernet transmit. +*/ +#define BD_ENET_TX_READY ((ushort)0x8000) +#define BD_ENET_TX_PAD ((ushort)0x4000) +#define BD_ENET_TX_WRAP ((ushort)0x2000) +#define BD_ENET_TX_INTR ((ushort)0x1000) +#define BD_ENET_TX_LAST ((ushort)0x0800) +#define BD_ENET_TX_TC ((ushort)0x0400) +#define BD_ENET_TX_DEF ((ushort)0x0200) +#define BD_ENET_TX_HB ((ushort)0x0100) +#define BD_ENET_TX_LC ((ushort)0x0080) +#define BD_ENET_TX_RL ((ushort)0x0040) +#define BD_ENET_TX_RCMASK ((ushort)0x003c) +#define BD_ENET_TX_UN ((ushort)0x0002) +#define BD_ENET_TX_CSL ((ushort)0x0001) +#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ + +/* SCC as UART +*/ +typedef struct scc_uart { + sccp_t scc_genscc; + uint scc_res1; /* Reserved */ + uint scc_res2; /* Reserved */ + ushort scc_maxidl; /* Maximum idle chars */ + ushort scc_idlc; /* temp idle counter */ + ushort scc_brkcr; /* Break count register */ + ushort scc_parec; /* receive parity error counter */ + ushort scc_frmec; /* receive framing error counter */ + ushort scc_nosec; /* receive noise counter */ + ushort scc_brkec; /* receive break condition counter */ + ushort scc_brkln; /* last received break length */ + ushort scc_uaddr1; /* UART address character 1 */ + ushort scc_uaddr2; /* UART address character 2 */ + ushort scc_rtemp; /* Temp storage */ + ushort scc_toseq; /* Transmit out of sequence char */ + ushort scc_char1; /* control character 1 */ + ushort scc_char2; /* control character 2 */ + ushort scc_char3; /* control character 3 */ + ushort scc_char4; /* control character 4 */ + ushort scc_char5; /* control character 5 */ + ushort scc_char6; /* control character 6 */ + ushort scc_char7; /* control character 7 */ + ushort scc_char8; /* control character 8 */ + ushort scc_rccm; /* receive control character mask */ + ushort scc_rccr; /* receive control character register */ + ushort scc_rlbc; /* receive last break character */ +} scc_uart_t; + +/* SCC Event and Mask registers when it is used as a UART. +*/ +#define UART_SCCM_GLR ((ushort)0x1000) +#define UART_SCCM_GLT ((ushort)0x0800) +#define UART_SCCM_AB ((ushort)0x0200) +#define UART_SCCM_IDL ((ushort)0x0100) +#define UART_SCCM_GRA ((ushort)0x0080) +#define UART_SCCM_BRKE ((ushort)0x0040) +#define UART_SCCM_BRKS ((ushort)0x0020) +#define UART_SCCM_CCR ((ushort)0x0008) +#define UART_SCCM_BSY ((ushort)0x0004) +#define UART_SCCM_TX ((ushort)0x0002) +#define UART_SCCM_RX ((ushort)0x0001) + +/* The SCC PSMR when used as a UART. +*/ +#define SCU_PSMR_FLC ((ushort)0x8000) +#define SCU_PSMR_SL ((ushort)0x4000) +#define SCU_PSMR_CL ((ushort)0x3000) +#define SCU_PSMR_UM ((ushort)0x0c00) +#define SCU_PSMR_FRZ ((ushort)0x0200) +#define SCU_PSMR_RZS ((ushort)0x0100) +#define SCU_PSMR_SYN ((ushort)0x0080) +#define SCU_PSMR_DRT ((ushort)0x0040) +#define SCU_PSMR_PEN ((ushort)0x0010) +#define SCU_PSMR_RPM ((ushort)0x000c) +#define SCU_PSMR_REVP ((ushort)0x0008) +#define SCU_PSMR_TPM ((ushort)0x0003) +#define SCU_PSMR_TEVP ((ushort)0x0003) + +/* CPM Transparent mode SCC. + */ +typedef struct scc_trans { + sccp_t st_genscc; + uint st_cpres; /* Preset CRC */ + uint st_cmask; /* Constant mask for CRC */ +} scc_trans_t; + +#define BD_SCC_TX_LAST ((ushort)0x0800) + +/* IIC parameter RAM. +*/ +typedef struct iic { + ushort iic_rbase; /* Rx Buffer descriptor base address */ + ushort iic_tbase; /* Tx Buffer descriptor base address */ + u_char iic_rfcr; /* Rx function code */ + u_char iic_tfcr; /* Tx function code */ + ushort iic_mrblr; /* Max receive buffer length */ + uint iic_rstate; /* Internal */ + uint iic_rdp; /* Internal */ + ushort iic_rbptr; /* Internal */ + ushort iic_rbc; /* Internal */ + uint iic_rxtmp; /* Internal */ + uint iic_tstate; /* Internal */ + uint iic_tdp; /* Internal */ + ushort iic_tbptr; /* Internal */ + ushort iic_tbc; /* Internal */ + uint iic_txtmp; /* Internal */ + uint iic_res; /* reserved */ + ushort iic_rpbase; /* Relocation pointer */ + ushort iic_res2; /* reserved */ +} iic_t; + +/* SPI parameter RAM. +*/ +typedef struct spi { + ushort spi_rbase; /* Rx Buffer descriptor base address */ + ushort spi_tbase; /* Tx Buffer descriptor base address */ + u_char spi_rfcr; /* Rx function code */ + u_char spi_tfcr; /* Tx function code */ + ushort spi_mrblr; /* Max receive buffer length */ + uint spi_rstate; /* Internal */ + uint spi_rdp; /* Internal */ + ushort spi_rbptr; /* Internal */ + ushort spi_rbc; /* Internal */ + uint spi_rxtmp; /* Internal */ + uint spi_tstate; /* Internal */ + uint spi_tdp; /* Internal */ + ushort spi_tbptr; /* Internal */ + ushort spi_tbc; /* Internal */ + uint spi_txtmp; /* Internal */ + uint spi_res; + ushort spi_rpbase; /* Relocation pointer */ + ushort spi_res2; +} spi_t; + +/* SPI Mode register. +*/ +#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */ +#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */ +#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */ +#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */ +#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */ +#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */ +#define SPMODE_EN ((ushort)0x0100) /* Enable */ +#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */ +#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */ + +#define SPMODE_LEN(x) ((((x)-1)&0xF)<<4) +#define SPMODE_PM(x) ((x) &0xF) + +/* HDLC parameter RAM. +*/ + +typedef struct hdlc_pram_s { + /* + * SCC parameter RAM + */ + ushort rbase; /* Rx Buffer descriptor base address */ + ushort tbase; /* Tx Buffer descriptor base address */ + uchar rfcr; /* Rx function code */ + uchar tfcr; /* Tx function code */ + ushort mrblr; /* Rx buffer length */ + ulong rstate; /* Rx internal state */ + ulong rptr; /* Rx internal data pointer */ + ushort rbptr; /* rb BD Pointer */ + ushort rcount; /* Rx internal byte count */ + ulong rtemp; /* Rx temp */ + ulong tstate; /* Tx internal state */ + ulong tptr; /* Tx internal data pointer */ + ushort tbptr; /* Tx BD pointer */ + ushort tcount; /* Tx byte count */ + ulong ttemp; /* Tx temp */ + ulong rcrc; /* temp receive CRC */ + ulong tcrc; /* temp transmit CRC */ + /* + * HDLC specific parameter RAM + */ + uchar res[4]; /* reserved */ + ulong c_mask; /* CRC constant */ + ulong c_pres; /* CRC preset */ + ushort disfc; /* discarded frame counter */ + ushort crcec; /* CRC error counter */ + ushort abtsc; /* abort sequence counter */ + ushort nmarc; /* nonmatching address rx cnt */ + ushort retrc; /* frame retransmission cnt */ + ushort mflr; /* maximum frame length reg */ + ushort max_cnt; /* maximum length counter */ + ushort rfthr; /* received frames threshold */ + ushort rfcnt; /* received frames count */ + ushort hmask; /* user defined frm addr mask */ + ushort haddr1; /* user defined frm address 1 */ + ushort haddr2; /* user defined frm address 2 */ + ushort haddr3; /* user defined frm address 3 */ + ushort haddr4; /* user defined frm address 4 */ + ushort tmp; /* temp */ + ushort tmp_mb; /* temp */ +} hdlc_pram_t; + +/* CPM interrupts. There are nearly 32 interrupts generated by CPM + * channels or devices. All of these are presented to the PPC core + * as a single interrupt. The CPM interrupt handler dispatches its + * own handlers, in a similar fashion to the PPC core handler. We + * use the table as defined in the manuals (i.e. no special high + * priority and SCC1 == SCCa, etc...). + */ +#define CPMVEC_NR 32 +#define CPMVEC_PIO_PC15 ((ushort)0x1f) +#define CPMVEC_SCC1 ((ushort)0x1e) +#define CPMVEC_SCC2 ((ushort)0x1d) +#define CPMVEC_SCC3 ((ushort)0x1c) +#define CPMVEC_SCC4 ((ushort)0x1b) +#define CPMVEC_PIO_PC14 ((ushort)0x1a) +#define CPMVEC_TIMER1 ((ushort)0x19) +#define CPMVEC_PIO_PC13 ((ushort)0x18) +#define CPMVEC_PIO_PC12 ((ushort)0x17) +#define CPMVEC_SDMA_CB_ERR ((ushort)0x16) +#define CPMVEC_IDMA1 ((ushort)0x15) +#define CPMVEC_IDMA2 ((ushort)0x14) +#define CPMVEC_TIMER2 ((ushort)0x12) +#define CPMVEC_RISCTIMER ((ushort)0x11) +#define CPMVEC_I2C ((ushort)0x10) +#define CPMVEC_PIO_PC11 ((ushort)0x0f) +#define CPMVEC_PIO_PC10 ((ushort)0x0e) +#define CPMVEC_TIMER3 ((ushort)0x0c) +#define CPMVEC_PIO_PC9 ((ushort)0x0b) +#define CPMVEC_PIO_PC8 ((ushort)0x0a) +#define CPMVEC_PIO_PC7 ((ushort)0x09) +#define CPMVEC_TIMER4 ((ushort)0x07) +#define CPMVEC_PIO_PC6 ((ushort)0x06) +#define CPMVEC_SPI ((ushort)0x05) +#define CPMVEC_SMC1 ((ushort)0x04) +#define CPMVEC_SMC2 ((ushort)0x03) +#define CPMVEC_PIO_PC5 ((ushort)0x02) +#define CPMVEC_PIO_PC4 ((ushort)0x01) +#define CPMVEC_ERROR ((ushort)0x00) + +extern void irq_install_handler(int vec, void (*handler)(void *), void *dev_id); + +/* CPM interrupt configuration vector. +*/ +#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */ +#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ +#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ +#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ +#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrrupt */ +#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ +#define CICR_IEN ((uint)0x00000080) /* Int. enable */ +#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ +#endif /* __CPM_8XX__ */ diff --git a/include/configs/ML2.h b/include/configs/ML2.h new file mode 100644 index 0000000..d662661 --- /dev/null +++ b/include/configs/ML2.h @@ -0,0 +1,246 @@ +/* + * ML2.h: ML2 specific config options + * + * Copyright 2002 Mind NV + * + * http://www.mind.be/ + * + * Author : Peter De Schrijver (p2@mind.be) + * + * Derived from : other configuration header files in this tree + * + * This software may be used and distributed according to the terms of + * the GNU General Public License (GPL) version 2, incorporated herein by + * reference. Drivers based on or derived from this code fall under the GPL + * and must retain the authorship, copyright and this license notice. This + * file is not a complete program and may only be used when the entire + * program is licensed under the GPL. + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_405 1 /* This is a PPC405 CPU */ +#define CONFIG_4xx 1 /* ...member of PPC4xx family */ +#define CONFIG_ML2 1 /* ...on a ML2 board */ + + +#define CFG_ENV_IS_IN_FLASH 1 + +#ifdef CFG_ENV_IS_IN_NVRAM +#undef CFG_ENV_IS_IN_FLASH +#else +#ifdef CFG_ENV_IS_IN_FLASH +#undef CFG_ENV_IS_IN_NVRAM +#endif +#endif + +#define CONFIG_BAUDRATE 9600 +#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */ + +#if 1 +#define CONFIG_BOOTCOMMAND "bootm" /* autoboot command */ +#else +#define CONFIG_BOOTCOMMAND "bootp" /* autoboot command */ +#endif + +#define CONFIG_PREBOOT "fsload 0x00100000 /boot/image" + +/* Size (bytes) of interrupt driven serial port buffer. + * Set to 0 to use polling instead of interrupts. + * Setting to 0 will also disable RTS/CTS handshaking. + */ +#if 0 +#define CONFIG_SERIAL_SOFTWARE_FIFO 4000 +#else +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#endif + +#if 0 +#define CONFIG_BOOTARGS "root=/dev/nfs " \ + "ip=192.168.2.176:192.168.2.190:192.168.2.79:255.255.255.0 " \ + "nfsroot=192.168.2.190:/home/stefan/cpci405/target_ftest4" +#else +#define CONFIG_BOOTARGS "root=/dev/mtdblock2 " \ + "console=ttyS0 console=tty" + +#endif + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + + + +#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & (~CFG_CMD_NET) & \ + (~CFG_CMD_RTC) & ~(CFG_CMD_PCI) & ~(CFG_CMD_I2C)) | \ + CFG_CMD_IRQ | \ + CFG_CMD_KGDB | \ + CFG_CMD_BEDBUG | \ + CFG_CMD_ELF | CFG_CMD_JFFS2 ) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +#define CONFIG_SYS_CLK_FREQ 50000000 + +#define CONFIG_SPD_EEPROM 1 /* use SPD EEPROM for setup */ + +/* + * 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 */ + +/* + * If CFG_EXT_SERIAL_CLOCK, then the UART divisor is 1. + * If CFG_405_UART_ERRATA_59, then UART divisor is 31. + * Otherwise, UART divisor is determined by CPU Clock and CFG_BASE_BAUD value. + * The Linux BASE_BAUD define should match this configuration. + * baseBaud = cpuClock/(uartDivisor*16) + * If CFG_405_UART_ERRATA_59 and 200MHz CPU clock, + * set Linux BASE_BAUD to 403200. + */ +#undef CFG_EXT_SERIAL_CLOCK /* external serial clock */ +#undef CFG_405_UART_ERRATA_59 /* 405GP/CR Rev. D silicon */ + +#define CFG_BASE_BAUD (3125000*16) +#define CFG_NS16550_CLK CFG_BASE_BAUD +#define CFG_DUART_CHAN 0 +#define CFG_NS16550_COM1 0xa0001003 +#define CFG_NS16550_COM2 0xa0011003 +#define CFG_NS16550_REG_SIZE -4 +#define CFG_NS16550 1 +#define CFG_INIT_CHAN1 1 +#define CFG_INIT_CHAN2 1 + +/* The following table includes the supported baudrates */ +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + + + +/*----------------------------------------------------------------------- + * 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 0x18000000 +#define CFG_MONITOR_BASE CFG_FLASH_BASE +#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 196 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) */ + +/* BEG ENVIRONNEMENT FLASH */ +#ifdef CFG_ENV_IS_IN_FLASH +#define CFG_ENV_OFFSET 0x00050000 /* Offset of Environment Sector */ +#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */ +#define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sector total size */ +#endif +/* END ENVIRONNEMENT FLASH */ +/*----------------------------------------------------------------------- + * NVRAM organization + */ +#define CFG_NVRAM_BASE_ADDR 0xf0000000 /* NVRAM base address */ +#define CFG_NVRAM_SIZE 0x1ff8 /* NVRAM size */ + +#ifdef CFG_ENV_IS_IN_NVRAM +#define CFG_ENV_SIZE 0x1000 /* Size of Environment vars */ +#define CFG_ENV_ADDR \ + (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE) /* Env */ +#endif +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_DCACHE_SIZE 8192 /* For IBM 405 CPUs */ +#define CFG_CACHELINE_SIZE 32 /* ... */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/* + * Init Memory Controller: + * + * BR0/1 and OR0/1 (FLASH) + */ + +#define FLASH_BASE0_PRELIM CFG_FLASH_BASE /* FLASH bank #0 */ +#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */ + + +/* Configuration Port location */ +#define CONFIG_PORT_ADDR 0xF0000500 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ + +#define CFG_INIT_RAM_ADDR 0x800000 /* inside of SDRAM */ +#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */ +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Definitions for Serial Presence Detect EEPROM address + * (to get SDRAM settings) + */ +#define SPD_EEPROM_ADDRESS 0x50 + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* JFFS2 stuff */ + +#define CFG_JFFS2_FIRST_BANK 0 +#define CFG_JFFS2_NUM_BANKS 1 +#define CFG_JFFS2_FIRST_SECTOR 1 +#endif /* __CONFIG_H */ diff --git a/include/configs/MOUSSE.h b/include/configs/MOUSSE.h new file mode 100644 index 0000000..109ed3d --- /dev/null +++ b/include/configs/MOUSSE.h @@ -0,0 +1,332 @@ +/* + * (C) Copyright 2000, 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 + * James F. Dougherty (jfd@cs.stanford.edu) + * + * 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 + */ + +/* + * + * Configuration settings for the MOUSSE board. + * See also: http://www.vooha.com/ + * + */ + +/* ------------------------------------------------------------------------- */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC824X 1 +#define CONFIG_MPC8240 1 +#define CONFIG_MOUSSE 1 +#define CFG_ADDR_MAP_B 1 +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 9600 +#if 1 +#define CONFIG_BOOTCOMMAND "tftp 100000 vmlinux.img;bootm" /* autoboot command */ +#else +#define CONFIG_BOOTCOMMAND "bootm ffe10000" +#endif +#define CONFIG_BOOTARGS "console=ttyS0 root=/dev/nfs rw nfsroot=209.128.93.133:/boot nfsaddrs=209.128.93.133:209.128.93.138" +#define CONFIG_BOOTDELAY 3 +#define CONFIG_COMMANDS (CONFIG_CMD_DFL|CFG_CMD_ASKENV|CFG_CMD_DATE) +#define CONFIG_ENV_OVERWRITE 1 +#define CONFIG_ETH_ADDR "00:10:18:10:00:06" + +#define CONFIG_DOS_PARTITION 1 /* MSDOS bootable partitiion support */ +/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) + */ +#include <cmd_confdefs.h> +#include "../board/mousse/mousse.h" + +/* + * Miscellaneous configurable options + */ +#undef CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=>" /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) +#define CFG_MAXARGS 8 /* Max number of command args */ + +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_LOAD_ADDR 0x00100000 /* Default load address */ + +/*----------------------------------------------------------------------- + * 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 + +#ifdef DEBUG +#define CFG_MONITOR_BASE CFG_SDRAM_BASE +#else +#define CFG_MONITOR_BASE CFG_FLASH_BASE +#endif + +#ifdef DEBUG +#define CFG_MONITOR_LEN (4 << 20) /* lots of mem ... */ +#else +#define CFG_MONITOR_LEN (512 << 10) /* 512K PLCC bootrom */ +#endif +#define CFG_MALLOC_LEN (2*(4096 << 10)) /* 2*4096kB for malloc() */ + +#define CFG_MEMTEST_START 0x00004000 /* memtest works on */ +#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */ + + +#define CFG_EUMB_ADDR 0xFC000000 + +#define CFG_ISA_MEM 0xFD000000 +#define CFG_ISA_IO 0xFE000000 + +#define CFG_FLASH_BASE 0xFFF00000 +#define CFG_FLASH_SIZE ((uint)(512 * 1024)) +#define CFG_RESET_ADDRESS 0xFFF00100 +#define FLASH_BASE0_PRELIM 0xFFF00000 /* 512K PLCC FLASH/AM29F040*/ +#define FLASH_BASE0_SIZE 0x80000 /* 512K */ +#define FLASH_BASE1_PRELIM 0xFFE10000 /* AMD 29LV160DB + 1MB - 64K FLASH0 SEG =960K + (size=0xf0000)*/ + +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * NS16550 Configuration + */ +#define CFG_NS16550 +#define CFG_NS16550_SERIAL + +#define CFG_NS16550_REG_SIZE 1 + +#define CFG_NS16550_CLK 18432000 + +#define CFG_NS16550_COM1 0xFFE08080 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_SDRAM_BASE + CFG_MONITOR_LEN +#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + * For the detail description refer to the MPC8240 user's manual. + */ + +#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */ +#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER 2 +#define CFG_HZ 1000 + +#define CFG_ETH_DEV_FN 0x00 +#define CFG_ETH_IOBASE 0x00104000 + + + /* Bit-field values for MCCR1. + */ +#define CFG_ROMNAL 8 +#define CFG_ROMFAL 8 + + /* Bit-field values for MCCR2. + */ +#define CFG_REFINT 0xf5 /* Refresh interval */ + + /* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4. + */ +#define CFG_BSTOPRE 0x79 + +#ifdef INCLUDE_ECC +#define USE_ECC 1 +#else /* INCLUDE_ECC */ +#define USE_ECC 0 +#endif /* INCLUDE_ECC */ + + + /* Bit-field values for MCCR3. + */ +#define CFG_REFREC 8 /* Refresh to activate interval */ +#define CFG_RDLAT (4+USE_ECC) /* Data latancy from read command */ + + /* Bit-field values for MCCR4. + */ +#define CFG_PRETOACT 3 /* Precharge to activate interval */ +#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */ +#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */ +#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */ +#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length */ +#define CFG_ACTORW 2 +#define CFG_REGISTERD_TYPE_BUFFER (1-USE_ECC) + +/* Memory bank settings. + * Only bits 20-29 are actually used from these vales to set the + * start/end addresses. The upper two bits will always be 0, and the lower + * 20 bits will be 0x00000 for a start address, or 0xfffff for an end + * address. Refer to the MPC8240 book. + */ +#define CFG_RAM_SIZE 0x04000000 /* 64MB */ + + +#define CFG_BANK0_START 0x00000000 +#define CFG_BANK0_END (CFG_RAM_SIZE - 1) +#define CFG_BANK0_ENABLE 1 +#define CFG_BANK1_START 0x3ff00000 +#define CFG_BANK1_END 0x3fffffff +#define CFG_BANK1_ENABLE 0 +#define CFG_BANK2_START 0x3ff00000 +#define CFG_BANK2_END 0x3fffffff +#define CFG_BANK2_ENABLE 0 +#define CFG_BANK3_START 0x3ff00000 +#define CFG_BANK3_END 0x3fffffff +#define CFG_BANK3_ENABLE 0 +#define CFG_BANK4_START 0x3ff00000 +#define CFG_BANK4_END 0x3fffffff +#define CFG_BANK4_ENABLE 0 +#define CFG_BANK5_START 0x3ff00000 +#define CFG_BANK5_END 0x3fffffff +#define CFG_BANK5_ENABLE 0 +#define CFG_BANK6_START 0x3ff00000 +#define CFG_BANK6_END 0x3fffffff +#define CFG_BANK6_ENABLE 0 +#define CFG_BANK7_START 0x3ff00000 +#define CFG_BANK7_END 0x3fffffff +#define CFG_BANK7_ENABLE 0 + +#define CFG_ODCR 0x7f + + +#define CFG_PGMAX 0x32 /* how long the 8240 reatins the currently accessed page in memory + see 8240 book for details*/ +#define PCI_MEM_SPACE1_START 0x80000000 +#define PCI_MEM_SPACE2_START 0xfd000000 + +/* IBAT/DBAT Configuration */ +/* Ram: 64MB, starts at address-0, r/w instruction/data */ +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_64M | BATU_VS | BATU_VP) +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_DBAT0U CFG_IBAT0U +#define CFG_DBAT0L CFG_IBAT0L + +/* MPLD/Port-X I/O Space : data and instruction read/write, cache-inhibit */ +#define CFG_IBAT1U (PORTX_DEV_BASE | BATU_BL_128M | BATU_VS | BATU_VP) +#if 0 +#define CFG_IBAT1L (PORTX_DEV_BASE | BATL_PP_10 | BATL_MEMCOHERENCE |\ + BATL_WRITETHROUGH | BATL_CACHEINHIBIT) +#else +#define CFG_IBAT1L (PORTX_DEV_BASE | BATL_PP_10 |BATL_CACHEINHIBIT) +#endif +#define CFG_DBAT1U CFG_IBAT1U +#define CFG_DBAT1L CFG_IBAT1L + +/* PCI Memory region 1: 0x8XXX_XXXX PCI Mem space: EUMBAR, etc - 16MB */ +#define CFG_IBAT2U (PCI_MEM_SPACE1_START|BATU_BL_16M | BATU_VS | BATU_VP) +#define CFG_IBAT2L (PCI_MEM_SPACE1_START|BATL_PP_10 | BATL_GUARDEDSTORAGE|BATL_CACHEINHIBIT) +#define CFG_DBAT2U CFG_IBAT2U +#define CFG_DBAT2L CFG_IBAT2L + +/* PCI Memory region 2: PCI Devices in 0xFD space */ +#define CFG_IBAT3U (PCI_MEM_SPACE2_START|BATU_BL_16M | BATU_VS | BATU_VP) +#define CFG_IBAT3L (PCI_MEM_SPACE2_START|BATL_PP_10 | BATL_GUARDEDSTORAGE | BATL_CACHEINHIBIT) +#define CFG_DBAT3U CFG_IBAT3U +#define CFG_DBAT3L CFG_IBAT3L + + +/* + * 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 3 /* Max number of flash banks */ +#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors in one bank */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#if 0 +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_OFFSET 0x8000 /* Offset of the Environment Sector */ +#define CFG_ENV_SIZE 0x4000 /* Size of the Environment Sector */ +#else +#define CFG_ENV_IS_IN_NVRAM 1 +#define CFG_ENV_ADDR NV_OFF_U_BOOT_ADDR /* PortX NVM Free addr*/ +#define CFG_ENV_OFFSET CFG_ENV_ADDR +#define CFG_ENV_SIZE NV_U_BOOT_ENV_SIZE /* 2K */ +#endif +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 + + + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +/* Localizations */ +#if 0 +#define CONFIG_ETHADDR 0:0:0:0:1:d +#define CONFIG_IPADDR 172.16.40.113 +#define CONFIG_SERVERIP 172.16.40.111 +#else +#define CONFIG_ETHADDR 0:0:0:0:1:d +#define CONFIG_IPADDR 209.128.93.138 +#define CONFIG_SERVERIP 209.128.93.133 +#endif + +/*----------------------------------------------------------------------- + * PCI stuff + *----------------------------------------------------------------------- + */ +#define CONFIG_PCI /* include pci support */ +#undef CONFIG_PCI_PNP + +#define CONFIG_NET_MULTI /* Multi ethernet cards support */ + +#define CONFIG_TULIP + +#endif /* __CONFIG_H */ + + diff --git a/include/configs/csb226.h b/include/configs/csb226.h new file mode 100644 index 0000000..13cf60f --- /dev/null +++ b/include/configs/csb226.h @@ -0,0 +1,213 @@ +/* + * (C) Copyright 2000, 2001, 2002 + * Robert Schwebel, Pengutronix, r.schwebel@pengutronix.de. + * + * Configuration for the Cogent CSB226 board. For details see + * http://www.cogcomp.com/csb_csb226.htm + * + * 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/configs/csb226.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * If we are developing, we might want to start U-Boot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#define CONFIG_INIT_CRITICAL /* undef for developing */ + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_PXA250 1 /* This is an PXA250 CPU */ +#define CONFIG_CSB226 1 /* on a CSB226 board */ + +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + /* for timer/console/ethernet */ +/* + * Hardware drivers + */ + +/* + * select serial console configuration + */ +#define CONFIG_FFUART 1 /* we use FFUART on CSB226 */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE 19200 + +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#define CONFIG_BOOTDELAY 10 +#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,115200" +#define CONFIG_ETHADDR FF:FF:FF:FF:FF:FF +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_IPADDR 192.168.1.56 +#define CONFIG_SERVERIP 192.168.1.2 +#define CONFIG_BOOTCOMMAND "" + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ + +/* + * Size of malloc() pool; this lives below the uppermost 128 KiB which are + * used for the RAM copy of the uboot code + * + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) + +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#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 0xa0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR 0xa7fe0000 /* default load address */ + /* RS: where is this documented? */ + /* RS: is this where U-Boot is */ + /* RS: relocated to in RAM? */ + +#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */ + /* RS: the oscillator is actually 3680130?? */ +#define CFG_CPUSPEED 0x141 /* set core clock to 200/200/100 MHz */ + /* 0101000001 */ + /* ^^^^^ Memory Speed 99.53 MHz */ + /* ^^ Run Mode Speed = 2x Mem Speed */ + /* ^^ Turbo Mode Sp. = 1x Run M. Sp. */ + +#define CFG_MONITOR_LEN 0x20000 /* 128 KiB */ + + /* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +/* + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB */ + +#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ +#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */ + +#define CFG_DRAM_BASE 0xa0000000 /* RAM starts here */ +#define CFG_DRAM_SIZE 0x02000000 + +#define CFG_FLASH_BASE PHYS_FLASH_1 + +/* + * GPIO settings + */ +#define CFG_GPSR0_VAL 0xFFFFFFFF +#define CFG_GPSR1_VAL 0xFFFFFFFF +#define CFG_GPSR2_VAL 0xFFFFFFFF +#define CFG_GPCR0_VAL 0x08022080 +#define CFG_GPCR1_VAL 0x00000000 +#define CFG_GPCR2_VAL 0x00000000 +#define CFG_GPDR0_VAL 0xCD82A858 +#define CFG_GPDR1_VAL 0xFCFFAB80 +#define CFG_GPDR2_VAL 0x0001FFFF +#define CFG_GAFR0_L_VAL 0x80000000 +#define CFG_GAFR0_U_VAL 0xA5254010 +#define CFG_GAFR1_L_VAL 0x599A9550 +#define CFG_GAFR1_U_VAL 0xAAA5AAAA +#define CFG_GAFR2_L_VAL 0xAAAAAAAA +#define CFG_GAFR2_U_VAL 0x00000002 + +/* FIXME: set GPIO_RER/FER */ + +#define CFG_PSSR_VAL 0x20 + +/* + * Memory settings + */ +#define CFG_MSC0_VAL 0x2EF025D0 +#define CFG_MSC1_VAL 0x00003F64 +#define CFG_MSC2_VAL 0x00000000 +#define CFG_MDCNFG_VAL 0x09a909a9 +#define CFG_MDREFR_VAL 0x03ca0030 +/* #define CFG_MDREFR_VAL_100 ??? */ +#define CFG_MDMRS_VAL 0x00220022 + +/* + * PCMCIA and CF Interfaces + */ +#define CFG_MECR_VAL 0x00000000 +#define CFG_MCMEM0_VAL 0x00000000 +#define CFG_MCMEM1_VAL 0x00000000 +#define CFG_MCATT0_VAL 0x00000000 +#define CFG_MCATT1_VAL 0x00000000 +#define CFG_MCIO0_VAL 0x00000000 +#define CFG_MCIO1_VAL 0x00000000 + +/* +#define _LED 0x08000010 +#define LED_BLANK (0x08000040) +*/ + +/* + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 128 /* max number of sect. on one chip */ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */ + +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C000) + /* Addr of Environment Sector */ +#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ + +#endif /* __CONFIG_H */ diff --git a/include/configs/gw8260.h b/include/configs/gw8260.h new file mode 100644 index 0000000..0e9a4ec --- /dev/null +++ b/include/configs/gw8260.h @@ -0,0 +1,820 @@ +/* + * (C) Copyright 2000 + * Murray Jensen <Murray.Jensen@cmst.csiro.au> + * + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jmonkman@adventnetworks.com> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Oliver Brown <obrown@adventnetworks.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/*********************************************************************/ +/* DESCRIPTION: + * This file contains the board configuartion for the GW8260 board. + * + * MODULE DEPENDENCY: + * None + * + * RESTRICTIONS/LIMITATIONS: + * None + * + * Copyright (c) 2001, Advent Networks, Inc. + */ +/*********************************************************************/ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* Enable debug prints */ +#undef DEBUG /* General debug */ +#undef DEBUG_BOOTP_EXT /* Debug received vendor fields */ + +/* What is the oscillator's (UX2) frequency in Hz? */ +#define CONFIG_8260_CLKIN (66 * 1000 * 1000) + +/*----------------------------------------------------------------------- + * MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual + *----------------------------------------------------------------------- + * What should MODCK_H be? It is dependent on the oscillator + * frequency, MODCK[1-3], and desired CPM and core frequencies. + * Here are some example values (all frequencies are in MHz): + * + * MODCK_H MODCK[1-3] Osc CPM Core S2-6 S2-7 S2-8 + * ------- ---------- --- --- ---- ----- ----- ----- + * 0x5 0x5 66 133 133 Open Close Open + * 0x5 0x6 66 133 166 Open Open Close + * 0x5 0x7 66 133 200 Open Open Open + * 0x6 0x0 66 133 233 Close Close Close + * 0x6 0x1 66 133 266 Close Close Open + * 0x6 0x2 66 133 300 Close Open Close + */ +#define CFG_SBC_MODCK_H 0x05 + +/* Define this if you want to boot from 0x00000100. If you don't define + * this, you will need to program the bootloader to 0xfff00000, and + * get the hardware reset config words at 0xfe000000. The simplest + * way to do that is to program the bootloader at both addresses. + * It is suggested that you just let U-Boot live at 0x00000000. + */ +#define CFG_SBC_BOOT_LOW 1 + +/* What should the base address of the main FLASH be and how big is + * it (in MBytes)? This must contain TEXT_BASE from board/sbc8260/config.mk + * The main FLASH is whichever is connected to *CS0. U-Boot expects + * this to be the SIMM. + */ +#define CFG_FLASH0_BASE 0x40000000 +#define CFG_FLASH0_SIZE 8 + +/* Define CFG_FLASH_CHECKSUM to enable flash checksum during boot. + * Note: the 'flashchecksum' environment variable must also be set to 'y'. + */ +#define CFG_FLASH_CHECKSUM + +/* What should be the base address of SDRAM DIMM and how big is + * it (in Mbytes)? + */ +#define CFG_SDRAM0_BASE 0x00000000 +#define CFG_SDRAM0_SIZE 64 + +/* + * DRAM tests + * CFG_DRAM_TEST - enables the following tests. + * + * CFG_DRAM_TEST_DATA - Enables test for shorted or open data lines + * Environment variable 'test_dram_data' must be + * set to 'y'. + * CFG_DRAM_TEST_DATA - Enables test to verify that each word is uniquely + * addressable. Environment variable + * 'test_dram_address' must be set to 'y'. + * CFG_DRAM_TEST_WALK - Enables test a 64-bit walking ones pattern test. + * This test takes about 6 minutes to test 64 MB. + * Environment variable 'test_dram_walk' must be + * set to 'y'. + */ +#define CFG_DRAM_TEST +#if defined(CFG_DRAM_TEST) +#define CFG_DRAM_TEST_DATA +#define CFG_DRAM_TEST_ADDRESS +#define CFG_DRAM_TEST_WALK +#endif /* CFG_DRAM_TEST */ + +/* + * GW8260 with 16 MB DIMM: + * + * 0x0000 0000 Exception Vector code, 8k + * : + * 0x0000 1FFF + * 0x0000 2000 Free for Application Use + * : + * : + * + * : + * : + * 0x00F5 FF30 Monitor Stack (Growing downward) + * Monitor Stack Buffer (0x80) + * 0x00F5 FFB0 Board Info Data + * 0x00F6 0000 Malloc Arena + * : CFG_ENV_SECT_SIZE, 256k + * : CFG_MALLOC_LEN, 128k + * 0x00FC 0000 RAM Copy of Monitor Code + * : CFG_MONITOR_LEN, 256k + * 0x00FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1 + */ + +/* + * GW8260 with 64 MB DIMM: + * + * 0x0000 0000 Exception Vector code, 8k + * : + * 0x0000 1FFF + * 0x0000 2000 Free for Application Use + * : + * : + * + * : + * : + * 0x03F5 FF30 Monitor Stack (Growing downward) + * Monitor Stack Buffer (0x80) + * 0x03F5 FFB0 Board Info Data + * 0x03F6 0000 Malloc Arena + * : CFG_ENV_SECT_SIZE, 256k + * : CFG_MALLOC_LEN, 128k + * 0x03FC 0000 RAM Copy of Monitor Code + * : CFG_MONITOR_LEN, 256k + * 0x03FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1 + */ + + +/* + * select serial console configuration + * + * if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then + * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4 + * for SCC). + * + * if CONFIG_CONS_NONE is defined, then the serial console routines must + * defined elsewhere. + */ +#define CONFIG_CONS_ON_SMC 1 /* define if console on SMC */ +#undef CONFIG_CONS_ON_SCC /* define if console on SCC */ +#undef CONFIG_CONS_NONE /* define if console on neither */ +#define CONFIG_CONS_INDEX 1 /* which SMC/SCC channel for console */ + +/* + * select ethernet configuration + * + * if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then + * CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3 + * for FCC) + * + * if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be + * defined elsewhere (as for the console), or CFG_CMD_NET must be removed + * from CONFIG_COMMANDS to remove support for networking. + */ + +#undef CONFIG_ETHER_ON_SCC +#define CONFIG_ETHER_ON_FCC +#undef CONFIG_ETHER_NONE /* define if ethernet on neither */ + +#ifdef CONFIG_ETHER_ON_SCC +#define CONFIG_ETHER_INDEX 1 /* which SCC/FCC channel for ethernet */ +#endif /* CONFIG_ETHER_ON_SCC */ + +#ifdef CONFIG_ETHER_ON_FCC +#define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */ +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +/* + * Port pins used for bit-banged MII communictions (if applicable). + */ +#define MDIO_PORT 2 /* Port C */ +#define MDIO_ACTIVE (iop->pdir |= 0x00400000) +#define MDIO_TRISTATE (iop->pdir &= ~0x00400000) +#define MDIO_READ ((iop->pdat & 0x00400000) != 0) + +#define MDIO(bit) if(bit) iop->pdat |= 0x00400000; \ + else iop->pdat &= ~0x00400000 + +#define MDC(bit) if(bit) iop->pdat |= 0x00200000; \ + else iop->pdat &= ~0x00200000 + +#define MIIDELAY udelay(1) +#endif /* CONFIG_ETHER_ON_FCC */ + +#if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2) + +/* + * - Rx-CLK is CLK13 + * - Tx-CLK is CLK14 + * - Select bus for bd/buffers (see 28-13) + * - Enable Full Duplex in FSMR + */ +# define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK) +# define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14) +# define CFG_CPMFCR_RAMTYPE 0 +# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB) + +#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 3) + +/* + * - Rx-CLK is CLK15 + * - Tx-CLK is CLK16 + * - Select bus for bd/buffers (see 28-13) + * - Enable Full Duplex in FSMR + */ +# define CFG_CMXFCR_MASK (CMXFCR_FC3|CMXFCR_RF3CS_MSK|CMXFCR_TF3CS_MSK) +# define CFG_CMXFCR_VALUE (CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16) +# define CFG_CPMFCR_RAMTYPE 0 +# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB) + +#endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */ + +/* Define this to reserve an entire FLASH sector (256 KB) for + * environment variables. Otherwise, the environment will be + * put in the same sector as U-Boot, and changing variables + * will erase U-Boot temporarily + */ +#define CFG_ENV_IN_OWN_SECT + +/* Define to allow the user to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* What should the console's baud rate be? */ +#define CONFIG_BAUDRATE 115200 + +/* Ethernet MAC address - This is set to all zeros to force an + * an error if we use BOOTP without setting + * the MAC address + */ +#define CONFIG_ETHADDR 00:00:00:00:00:00 + +/* Set to a positive value to delay for running BOOTCOMMAND */ +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ + +/* Be selective on what keys can delay or stop the autoboot process + * To stop use: " " + */ +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, press \" \" to stop\n" +#define CONFIG_AUTOBOOT_STOP_STR " " +#undef CONFIG_AUTOBOOT_DELAY_STR +#define DEBUG_BOOTKEYS 0 + +/* Add support for a few extra bootp options like: + * - File size + * - DNS + */ +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \ + CONFIG_BOOTP_BOOTFILESIZE | \ + CONFIG_BOOTP_DNS) + +/* undef this to save memory */ +#define CFG_LONGHELP + +/* Monitor Command Prompt */ +#define CFG_PROMPT "=> " + +/* What U-Boot subsytems do you want enabled? */ +#define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_BEDBUG | \ + CFG_CMD_ELF | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_REGINFO | \ + CFG_CMD_IMMAP | \ + CFG_CMD_MII) + +/* Where do the internal registers live? */ +#define CFG_IMMR 0xf0000000 + +/* Use the HUSH parser */ +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* What is the address of IO controller */ +#define CFG_IO_BASE 0xe0000000 + +/***************************************************************************** + * + * You should not have to modify any of the following settings + * + *****************************************************************************/ + +#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */ +#define CONFIG_GW8260 1 /* on an GW8260 Board */ + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +/* + * Miscellaneous configurable options + */ +#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 + +/* Print Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT)+16) + +#define CFG_MAXARGS 8 /* max number of command args */ + +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +/* Convert clocks to MHZ when passing board info to kernel. + * This must be defined for eariler 2.4 kernels (~2.4.4). + */ +#define CONFIG_CLOCKS_IN_MHZ + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + + +/* memtest works from the end of the exception vector table + * to the end of the DRAM less monitor and malloc area + */ +#define CFG_MEMTEST_START 0x2000 + +#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */ + +#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \ + + CFG_MALLOC_LEN \ + + CFG_ENV_SECT_SIZE \ + + CFG_STACK_USAGE ) + +#define CFG_MEMTEST_END ( CFG_SDRAM_SIZE * 1024 * 1024 \ + - CFG_MEM_END_USAGE ) + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ + +#define CFG_FLASH_BASE CFG_FLASH0_BASE +#define CFG_FLASH_SIZE CFG_FLASH0_SIZE +#define CFG_SDRAM_BASE CFG_SDRAM0_BASE +#define CFG_SDRAM_SIZE CFG_SDRAM0_SIZE + +/*----------------------------------------------------------------------- + * Hard Reset Configuration Words + */ +#if defined(CFG_SBC_BOOT_LOW) +# define CFG_SBC_HRCW_BOOT_FLAGS (HRCW_CIP | HRCW_BMS) +#else +# define CFG_SBC_HRCW_BOOT_FLAGS (0) +#endif /* defined(CFG_SBC_BOOT_LOW) */ + +/* get the HRCW ISB field from CFG_IMMR */ +#define CFG_SBC_HRCW_IMMR ( ((CFG_IMMR & 0x10000000) >> 10) | \ + ((CFG_IMMR & 0x01000000) >> 7) | \ + ((CFG_IMMR & 0x00100000) >> 4) ) + +#define CFG_HRCW_MASTER ( HRCW_BPS11 | \ + HRCW_DPPC11 | \ + CFG_SBC_HRCW_IMMR | \ + HRCW_MMR00 | \ + HRCW_LBPC11 | \ + HRCW_APPC10 | \ + HRCW_CS10PC00 | \ + (CFG_SBC_MODCK_H & HRCW_MODCK_H1111) | \ + CFG_SBC_HRCW_BOOT_FLAGS ) + +/* no slaves */ +#define CFG_HRCW_SLAVE1 0 +#define CFG_HRCW_SLAVE2 0 +#define CFG_HRCW_SLAVE3 0 +#define CFG_HRCW_SLAVE4 0 +#define CFG_HRCW_SLAVE5 0 +#define CFG_HRCW_SLAVE6 0 +#define CFG_HRCW_SLAVE7 0 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + * Note also that the logic that sets CFG_RAMBOOT is platform dependent. + */ +#define CFG_MONITOR_BASE CFG_FLASH0_BASE + +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 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 * 1024 * 1024) /* Initial Memory map for Linux */ + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 32 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 8000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 1 /* Timeout for Flash Write (in ms) */ + +#define CFG_ENV_IS_IN_FLASH 1 + +#ifdef CFG_ENV_IN_OWN_SECT +# define CFG_ENV_ADDR (CFG_MONITOR_BASE + (256 * 1024)) +# define CFG_ENV_SECT_SIZE (256 * 1024) +#else +# define CFG_ENV_SIZE (16 * 1024)/* Size of Environment Sector */ +# define CFG_ENV_ADD ((CFG_MONITOR_BASE + CFG_MONITOR_LEN) - CFG_ENV_SIZE) +# define CFG_ENV_SECT_SIZE (256 * 1024)/* see README - env sect real size */ +#endif /* CFG_ENV_IN_OWN_SECT */ + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * HIDx - Hardware Implementation-dependent Registers 2-11 + *----------------------------------------------------------------------- + * HID0 also contains cache control - initially enable both caches and + * invalidate contents, then the final state leaves only the instruction + * cache enabled. Note that Power-On and Hard reset invalidate the caches, + * but Soft reset does not. + * + * HID1 has only read-only information - nothing to set. + */ +#define CFG_HID0_INIT (HID0_ICE |\ + HID0_DCE |\ + HID0_ICFI |\ + HID0_DCI |\ + HID0_IFEM |\ + HID0_ABE) + +#define CFG_HID0_FINAL (HID0_ICE |\ + HID0_IFEM |\ + HID0_ABE |\ + HID0_EMCP) +#define CFG_HID2 0 + +/*----------------------------------------------------------------------- + * RMR - Reset Mode Register + *----------------------------------------------------------------------- + */ +#define CFG_RMR 0 + +/*----------------------------------------------------------------------- + * BCR - Bus Configuration 4-25 + *----------------------------------------------------------------------- + */ +#define CFG_BCR (BCR_ETM) + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration 4-31 + *----------------------------------------------------------------------- + */ +#define CFG_SIUMCR (SIUMCR_DPPC11 |\ + SIUMCR_L2CPC00 |\ + SIUMCR_APPC10 |\ + SIUMCR_MMR00) + + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable + */ +#define CFG_SYPCR (SYPCR_SWTC |\ + SYPCR_BMT |\ + SYPCR_PBME |\ + SYPCR_LBME |\ + SYPCR_SWRI |\ + SYPCR_SWP) + +/*----------------------------------------------------------------------- + * TMCNTSC - Time Counter Status and Control 4-40 + *----------------------------------------------------------------------- + * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk, + * and enable Time Counter + */ +#define CFG_TMCNTSC (TMCNTSC_SEC |\ + TMCNTSC_ALR |\ + TMCNTSC_TCF |\ + TMCNTSC_TCE) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 4-42 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable + * Periodic timer + */ +#define CFG_PISCR (PISCR_PS |\ + PISCR_PTF |\ + PISCR_PTE) + +/*----------------------------------------------------------------------- + * SCCR - System Clock Control 9-8 + *----------------------------------------------------------------------- + */ +#define CFG_SCCR 0 + +/*----------------------------------------------------------------------- + * RCCR - RISC Controller Configuration 13-7 + *----------------------------------------------------------------------- + */ +#define CFG_RCCR 0 + +/* + * Initialize Memory Controller: + * + * Bank Bus Machine PortSz Device + * ---- --- ------- ------ ------ + * 0 60x GPCM 32 bit FLASH (SIMM - 4MB) + * 1 60x GPCM 32 bit unused + * 2 60x SDRAM 64 bit SDRAM (DIMM - 16MB or 64MB) + * 3 60x SDRAM 64 bit unused + * 4 Local GPCM 8 bit IO (on board - 64k) + * 5 60x GPCM 8 bit unused + * 6 60x GPCM 8 bit unused + * 7 60x GPCM 8 bit unused + * + */ + +/*----------------------------------------------------------------------- + * BR0 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR0 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 0,1 - FLASH SIMM + * + * This expects the FLASH SIMM to be connected to *CS0 + * It consists of 4 AM29F016D parts. + * + * Note: For the 8 MB SIMM, *CS1 is unused. + */ + +/* BR0 is configured as follows: + * + * - Base address of 0x40000000 + * - 32 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR0_PRELIM ((CFG_FLASH0_BASE & BRx_BA_MSK) |\ + BRx_PS_32 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR0 is configured as follows: + * + * - 8 MB + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 5 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +#define CFG_OR0_PRELIM (MEG_TO_AM(CFG_FLASH0_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) + +/*----------------------------------------------------------------------- + * BR2 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR2 - Option Register + * Ref: Section 10.3.2 on page 10-16 + *----------------------------------------------------------------------- + */ + +/* Bank 2 - SDRAM DIMM + * + * 16MB DIMM: P/N + * 64MB DIMM: P/N 1W-8864X8-4-P1-EST or + * MT4LSDT864AG-10EB1 (Micron) + * + * Note: *CS3 is unused for this DIMM + */ + +/* With a 16 MB or 64 MB DIMM, the BR2 is configured as follows: + * + * - Base address of 0x00000000 + * - 64 bit port size (60x bus only) + * - Data errors checking is disabled + * - Read and write access + * - SDRAM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR2_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +/* With a 16 MB DIMM, the OR2 is configured as follows: + * + * - 16 MB + * - 2 internal banks per device + * - Row start address bit is A9 with PSDMR[PBI] = 0 + * - 11 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ +#if (CFG_SDRAM0_SIZE == 16) +#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\ + ORxS_BPD_2 |\ + ORxS_ROWST_PBI0_A9 |\ + ORxS_NUMR_11) + +/* With a 16 MB DIMM, the PSDMR is configured as follows: + * + * - Page Based Interleaving, + * - Refresh Enable, + * - Address Multiplexing where A5 is output on A14 pin + * (A6 on A15, and so on), + * - use address pins A16-A18 as bank select, + * - A9 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 3 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - CAS Latency is 2. + */ + +/*----------------------------------------------------------------------- + * PSDMR - 60x Bus SDRAM Mode Register + * Ref: Section 10.3.3 on page 10-21 + *----------------------------------------------------------------------- + */ +#define CFG_PSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A16_A18 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) +#endif /* (CFG_SDRAM0_SIZE == 16) */ + +/* With a 64 MB DIMM, the OR2 is configured as follows: + * + * - 64 MB + * - 4 internal banks per device + * - Row start address bit is A8 with PSDMR[PBI] = 0 + * - 12 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ +#if (CFG_SDRAM0_SIZE == 64) +#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\ + ORxS_BPD_4 |\ + ORxS_ROWST_PBI0_A8 |\ + ORxS_NUMR_12) + +/* With a 64 MB DIMM, the PSDMR is configured as follows: + * + * - Page Based Interleaving, + * - Refresh Enable, + * - Address Multiplexing where A5 is output on A14 pin + * (A6 on A15, and so on), + * - use address pins A14-A16 as bank select, + * - A9 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 3 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - CAS Latency is 2. + */ + +/*----------------------------------------------------------------------- + * PSDMR - 60x Bus SDRAM Mode Register + * Ref: Section 10.3.3 on page 10-21 + *----------------------------------------------------------------------- + */ +#define CFG_PSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A14_A16 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) +#endif /* (CFG_SDRAM0_SIZE == 64) */ + +#define CFG_PSRT 0x0e +#define CFG_MPTPR MPTPR_PTP_DIV32 + + +/*----------------------------------------------------------------------- + * BR4 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR4 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ +/* Bank 4 - Onboard Memory Mapped IO controller + * + * This expects the onboard IO controller to connected to *CS4 and + * the local bus. + * - Base address of 0xe0000000 + * - 8 bit port size (local bus only) + * - Read and write access + * - GPCM local bus + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + * - extended hold time + * - 11 wait states + */ + +#ifdef CFG_IO_BASE +# define CFG_BR4_PRELIM ((CFG_IO_BASE & BRx_BA_MSK) |\ + BRx_PS_8 |\ + BRx_MS_GPCM_L |\ + BRx_V) + +# define CFG_OR4_PRELIM (ORxG_AM_MSK |\ + ORxG_SCY_11_CLK |\ + ORxG_EHTR) +#endif /* CFG_IO_BASE */ + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ diff --git a/include/configs/ppmc8260.h b/include/configs/ppmc8260.h new file mode 100644 index 0000000..580b590 --- /dev/null +++ b/include/configs/ppmc8260.h @@ -0,0 +1,1004 @@ +/* + * (C) Copyright 2000 + * Murray Jensen <Murray.Jensen@cmst.csiro.au> + * + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * Configuation settings for the WindRiver PPMC8260 board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/***************************************************************************** + * + * These settings must match the way _your_ board is set up + * + *****************************************************************************/ + +/* What is the oscillator's (UX2) frequency in Hz? */ +#define CONFIG_8260_CLKIN (66 * 1000 * 1000) + +/*----------------------------------------------------------------------- + * MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual + *----------------------------------------------------------------------- + * What should MODCK_H be? It is dependent on the oscillator + * frequency, MODCK[1-3], and desired CPM and core frequencies. + * Here are some example values (all frequencies are in MHz): + * + * MODCK_H MODCK[1-3] Osc CPM Core S2-6 S2-7 S2-8 + * ------- ---------- --- --- ---- ----- ----- ----- + * 0x2 0x2 33 133 133 Close Open Close + * 0x2 0x3 33 133 166 Close Open Open + * 0x2 0x4 33 133 200 Open Close Close + * 0x2 0x5 33 133 233 Open Close Open + * 0x2 0x6 33 133 266 Open Open Close + * + * 0x5 0x5 66 133 133 Open Close Open + * 0x5 0x6 66 133 166 Open Open Close + * 0x5 0x7 66 133 200 Open Open Open + * 0x6 0x0 66 133 233 Close Close Close + * 0x6 0x1 66 133 266 Close Close Open + * 0x6 0x2 66 133 300 Close Open Close + */ +#define CFG_PPMC_MODCK_H 0x05 + +/* Define this if you want to boot from 0x00000100. If you don't define + * this, you will need to program the bootloader to 0xfff00000, and + * get the hardware reset config words at 0xfe000000. The simplest + * way to do that is to program the bootloader at both addresses. + * It is suggested that you just let U-Boot live at 0x00000000. + */ +#define CFG_PPMC_BOOT_LOW 1 + +/* What should the base address of the main FLASH be and how big is + * it (in MBytes)? This must contain TEXT_BASE from board/ppmc8260/config.mk + * The main FLASH is whichever is connected to *CS0. U-Boot expects + * this to be the SIMM. + */ +#define CFG_FLASH0_BASE 0xFE000000 +#define CFG_FLASH0_SIZE 16 + +/* What should be the base address of the first SDRAM DIMM and how big is + * it (in Mbytes)? +*/ +#define CFG_SDRAM0_BASE 0x00000000 +#define CFG_SDRAM0_SIZE 128 + +/* What should be the base address of the second SDRAM DIMM and how big is + * it (in Mbytes)? +*/ +#define CFG_SDRAM1_BASE 0x08000000 +#define CFG_SDRAM1_SIZE 128 + +/* What should be the base address of the on board SDRAM and how big is + * it (in Mbytes)? +*/ +#define CFG_SDRAM2_BASE 0x38000000 +#define CFG_SDRAM2_SIZE 16 + +/* What should be the base address of the MAILBOX and how big is it + * (in Bytes) + * The eeprom lives at CFG_MAILBOX_BASE + 0x80000000 + */ +#define CFG_MAILBOX_BASE 0x32000000 +#define CFG_MAILBOX_SIZE 8192 + +/* What is the base address of the I/O select lines and how big is it + * (In Mbytes)? + */ + +#define CFG_IOSELECT_BASE 0xE0000000 +#define CFG_IOSELECT_SIZE 32 + + +/* What should be the base address of the LEDs and switch S0? + * If you don't want them enabled, don't define this. + */ +#define CFG_LED_BASE 0xF1000000 + +/* + * PPMC8260 with 256 16 MB DIMM: + * + * 0x0000 0000 Exception Vector code, 8k + * : + * 0x0000 1FFF + * 0x0000 2000 Free for Application Use + * : + * : + * + * : + * : + * 0x0FF5 FF30 Monitor Stack (Growing downward) + * Monitor Stack Buffer (0x80) + * 0x0FF5 FFB0 Board Info Data + * 0x0FF6 0000 Malloc Arena + * : CFG_ENV_SECT_SIZE, 256k + * : CFG_MALLOC_LEN, 128k + * 0x0FFC 0000 RAM Copy of Monitor Code + * : CFG_MONITOR_LEN, 256k + * 0x0FFF FFFF [End of RAM], CFG_SDRAM_SIZE - 1 + */ + + +/* + * select serial console configuration + * + * if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then + * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4 + * for SCC). + * + * if CONFIG_CONS_NONE is defined, then the serial console routines must + * defined elsewhere. + * The console can be on SMC1 or SMC2 + */ +#define CONFIG_CONS_ON_SMC 1 /* define if console on SMC */ +#undef CONFIG_CONS_ON_SCC /* define if console on SCC */ +#undef CONFIG_CONS_NONE /* define if console on neither */ +#define CONFIG_CONS_INDEX 1 /* which SMC/SCC channel for console */ + +/* + * select ethernet configuration + * + * if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then + * CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3 + * for FCC) + * + * if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be + * defined elsewhere (as for the console), or CFG_CMD_NET must be removed + * from CONFIG_COMMANDS to remove support for networking. + */ + +#undef CONFIG_ETHER_ON_SCC /* define if ethernet on SCC */ +#define CONFIG_ETHER_ON_FCC /* define if ethernet on FCC */ +#undef CONFIG_ETHER_NONE /* define if ethernet on neither */ +#define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */ +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +/* + * Port pins used for bit-banged MII communictions (if applicable). + */ +#define MDIO_PORT 2 /* Port C */ +#define MDIO_ACTIVE (iop->pdir |= 0x00400000) +#define MDIO_TRISTATE (iop->pdir &= ~0x00400000) +#define MDIO_READ ((iop->pdat & 0x00400000) != 0) + +#define MDIO(bit) if(bit) iop->pdat |= 0x00400000; \ + else iop->pdat &= ~0x00400000 + +#define MDC(bit) if(bit) iop->pdat |= 0x00200000; \ + else iop->pdat &= ~0x00200000 + +#define MIIDELAY udelay(1) + + +/* Define this to reserve an entire FLASH sector (256 KB) for + * environment variables. Otherwise, the environment will be + * put in the same sector as U-Boot, and changing variables + * will erase U-Boot temporarily + */ +#define CFG_ENV_IN_OWN_SECT 1 + +/* Define to allow the user to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* What should the console's baud rate be? */ +#define CONFIG_BAUDRATE 9600 + +/* Ethernet MAC address */ + +#define CONFIG_ETHADDR 00:a0:1e:90:2b:00 + +/* Define this to set the last octet of the ethernet address + * from the DS0-DS7 switch and light the leds with the result + * The DS0-DS7 switch and the leds are backwards with respect + * to each other. DS7 is on the board edge side of both the + * led strip and the DS0-DS7 switch. + */ +#define CONFIG_MISC_INIT_R + +/* Set to a positive value to delay for running BOOTCOMMAND */ +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ + +#if 0 +/* Be selective on what keys can delay or stop the autoboot process + * To stop use: " " + */ +# define CONFIG_AUTOBOOT_KEYED +# define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, press \" \" to stop\n" +# define CONFIG_AUTOBOOT_STOP_STR " " +# undef CONFIG_AUTOBOOT_DELAY_STR +# define DEBUG_BOOTKEYS 0 +#endif + +/* Define a command string that is automatically executed when no character + * is read on the console interface withing "Boot Delay" after reset. + */ +#define CONFIG_BOOT_ROOT_INITRD 0 /* Use ram disk for the root file system */ +#define CONFIG_BOOT_ROOT_NFS 1 /* Use a NFS mounted root file system */ + +#if CONFIG_BOOT_ROOT_INITRD +#define CONFIG_BOOTCOMMAND \ + "version;" \ + "echo;" \ + "bootp;" \ + "setenv bootargs root=/dev/ram0 rw " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "bootm" +#endif /* CONFIG_BOOT_ROOT_INITRD */ + +#if CONFIG_BOOT_ROOT_NFS +#define CONFIG_BOOTCOMMAND \ + "version;" \ + "echo;" \ + "bootp;" \ + "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "bootm" +#endif /* CONFIG_BOOT_ROOT_NFS */ + +/* Add support for a few extra bootp options like: + * - File size + * - DNS + */ +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \ + CONFIG_BOOTP_BOOTFILESIZE | \ + CONFIG_BOOTP_DNS) + +/* undef this to save memory */ +#define CFG_LONGHELP + +/* Monitor Command Prompt */ +#define CFG_PROMPT "=> " + +/* What U-Boot subsytems do you want enabled? */ +#define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_ELF | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_REGINFO | \ + CFG_CMD_MEMTEST | \ + CFG_CMD_MII | \ + CFG_CMD_IMMAP) + + +/* Where do the internal registers live? */ +#define CFG_IMMR 0xf0000000 + +/***************************************************************************** + * + * You should not have to modify any of the following settings + * + *****************************************************************************/ + +#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */ +#define CONFIG_PPMC8260 1 /* on an Wind River PPMC8260 Board */ + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +/* + * Miscellaneous configurable options + */ +#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 + +/* Print Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT)+16) + +#define CFG_MAXARGS 32 /* max number of command args */ + +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_LOAD_ADDR 0x140000 /* default load address */ +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CFG_MEMTEST_START 0x2000 /* memtest works from the end of */ + /* the exception vector table */ + /* to the end of the DRAM */ + /* less monitor and malloc area */ +#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */ +#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \ + + CFG_MALLOC_LEN \ + + CFG_ENV_SECT_SIZE \ + + CFG_STACK_USAGE ) + +#define CFG_MEMTEST_END ( CFG_SDRAM_SIZE * 1024 * 1024 \ + - CFG_MEM_END_USAGE ) + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ + +#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1) +/* + * Attention: This is board specific + * - RX clk is CLK11 + * - TX clk is CLK12 + */ +#define CFG_CMXSCR_VALUE (CMXSCR_RS1CS_CLK11 |\ + CMXSCR_TS1CS_CLK12) + +#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2) +/* + * Attention: this is board-specific + * - Rx-CLK is CLK13 + * - Tx-CLK is CLK14 + * - Select bus for bd/buffers (see 28-13) + * - Enable Full Duplex in FSMR + */ +#define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK) +#define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14) +#define CFG_CPMFCR_RAMTYPE 0 +#define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB) +#endif /* CONFIG_ETHER_INDEX */ + +#define CFG_FLASH_BASE CFG_FLASH0_BASE +#define CFG_FLASH_SIZE CFG_FLASH0_SIZE +#define CFG_SDRAM_BASE CFG_SDRAM0_BASE +#define CFG_SDRAM_SIZE (CFG_SDRAM0_SIZE + CFG_SDRAM1_SIZE) + +/*----------------------------------------------------------------------- + * Hard Reset Configuration Words + */ +#if defined(CFG_PPMC_BOOT_LOW) +# define CFG_PPMC_HRCW_BOOT_FLAGS (HRCW_CIP | HRCW_BMS) +#else +# define CFG_PPMC_HRCW_BOOT_FLAGS (0) +#endif /* defined(CFG_PPMC_BOOT_LOW) */ + +/* get the HRCW ISB field from CFG_IMMR */ +#define CFG_PPMC_HRCW_IMMR ( ((CFG_IMMR & 0x10000000) >> 10) | \ + ((CFG_IMMR & 0x01000000) >> 7) | \ + ((CFG_IMMR & 0x00100000) >> 4) ) + +#define CFG_HRCW_MASTER ( HRCW_EBM | \ + HRCW_BPS11 | \ + HRCW_L2CPC10 | \ + HRCW_DPPC00 | \ + CFG_PPMC_HRCW_IMMR | \ + HRCW_MMR00 | \ + HRCW_LBPC00 | \ + HRCW_APPC10 | \ + HRCW_CS10PC00 | \ + (CFG_PPMC_MODCK_H & HRCW_MODCK_H1111) | \ + CFG_PPMC_HRCW_BOOT_FLAGS ) + +/* no slaves */ +#define CFG_HRCW_SLAVE1 0 +#define CFG_HRCW_SLAVE2 0 +#define CFG_HRCW_SLAVE3 0 +#define CFG_HRCW_SLAVE4 0 +#define CFG_HRCW_SLAVE5 0 +#define CFG_HRCW_SLAVE6 0 +#define CFG_HRCW_SLAVE7 0 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + * Note also that the logic that sets CFG_RAMBOOT is platform dependent. + */ +#define CFG_MONITOR_BASE CFG_FLASH0_BASE + +#ifndef CFG_MONITOR_BASE +#define CFG_MONITOR_BASE 0x0ff80000 +#endif + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +# define CFG_RAMBOOT +#endif + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 374 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* 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 and environment organization + */ + +#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ +#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_FLASH_INCREMENT 0 /* there is only one bank */ +#define CFG_FLASH_PROTECTION 1 /* use hardware protection */ +#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ + + +#ifndef CFG_RAMBOOT + +# define CFG_ENV_IS_IN_FLASH 1 +# ifdef CFG_ENV_IN_OWN_SECT +# define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) +# define CFG_ENV_SECT_SIZE 0x40000 +# else +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_MONITOR_LEN - CFG_ENV_SECT_SIZE) +# define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ +# define CFG_ENV_SECT_SIZE 0x40000 /* see README - env sect real size */ +# endif /* CFG_ENV_IN_OWN_SECT */ + +#else +# define CFG_ENV_IS_IN_FLASH 1 +# define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x40000) +#define CFG_ENV_SIZE 0x1000 +# define CFG_ENV_SECT_SIZE 0x40000 +#endif /* CFG_RAMBOOT */ + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * HIDx - Hardware Implementation-dependent Registers 2-11 + *----------------------------------------------------------------------- + * HID0 also contains cache control - initially enable both caches and + * invalidate contents, then the final state leaves only the instruction + * cache enabled. Note that Power-On and Hard reset invalidate the caches, + * but Soft reset does not. + * + * HID1 has only read-only information - nothing to set. + */ +#define CFG_HID0_INIT (HID0_ICE |\ + HID0_DCE |\ + HID0_ICFI |\ + HID0_DCI |\ + HID0_IFEM |\ + HID0_ABE) + +#define CFG_HID0_FINAL (HID0_ICE |\ + HID0_IFEM |\ + HID0_ABE |\ + HID0_EMCP) +#define CFG_HID2 0 + +/*----------------------------------------------------------------------- + * RMR - Reset Mode Register + *----------------------------------------------------------------------- + */ +#define CFG_RMR 0 + +/*----------------------------------------------------------------------- + * BCR - Bus Configuration 4-25 + *----------------------------------------------------------------------- + */ +#define CFG_BCR (BCR_EBM |\ + 0x30000000) + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration 4-31 + * Ref Section 4.3.2.6 page 4-31 + *----------------------------------------------------------------------- + */ + +#define CFG_SIUMCR (SIUMCR_ESE |\ + SIUMCR_DPPC00 |\ + SIUMCR_L2CPC10 |\ + SIUMCR_LBPC00 |\ + SIUMCR_APPC10 |\ + SIUMCR_CS10PC00 |\ + SIUMCR_BCTLC00 |\ + SIUMCR_MMR00) + + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable + */ +#define CFG_SYPCR (SYPCR_SWTC |\ + SYPCR_BMT |\ + SYPCR_PBME |\ + SYPCR_LBME |\ + SYPCR_SWRI |\ + SYPCR_SWP) + +/*----------------------------------------------------------------------- + * TMCNTSC - Time Counter Status and Control 4-40 + *----------------------------------------------------------------------- + * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk, + * and enable Time Counter + */ +#define CFG_TMCNTSC (TMCNTSC_SEC |\ + TMCNTSC_ALR |\ + TMCNTSC_TCF |\ + TMCNTSC_TCE) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 4-42 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable + * Periodic timer + */ +#define CFG_PISCR (PISCR_PS |\ + PISCR_PTF |\ + PISCR_PTE) + +/*----------------------------------------------------------------------- + * SCCR - System Clock Control 9-8 + *----------------------------------------------------------------------- + */ +#define CFG_SCCR 0 + +/*----------------------------------------------------------------------- + * RCCR - RISC Controller Configuration 13-7 + *----------------------------------------------------------------------- + */ +#define CFG_RCCR 0 + +/* + * Initialize Memory Controller: + * + * Bank Bus Machine PortSz Device + * ---- --- ------- ------ ------ + * 0 60x GPCM 32 bit FLASH (SIMM - 32MB) * + * 1 unused + * 2 60x SDRAM 64 bit SDRAM (DIMM - 128MB) + * 3 60x SDRAM 64 bit SDRAM (DIMM - 128MB) + * 4 Local SDRAM 32 bit SDRAM (on board - 16MB) + * 5 60x GPCM 8 bit Mailbox/EEPROM (8KB) + * 6 60x GPCM 8 bit FLASH (on board - 2MB) * + * 7 60x GPCM 8 bit LEDs, switches + * + * (*) This configuration requires the PPMC8260 be configured + * so that *CS0 goes to the FLASH SIMM, and *CS6 goes to + * the on board FLASH. In other words, JP24 should have + * pins 1 and 2 jumpered and pins 3 and 4 jumpered. + * + */ + +/*----------------------------------------------------------------------- + * BR0,BR1 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR0,OR1 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 0,1 - FLASH SIMM + * + * This expects the FLASH SIMM to be connected to *CS0 + * It consists of 4 AM29F080B parts. + * + * Note: For the 4 MB SIMM, *CS1 is unused. + */ + +/* BR0 is configured as follows: + * + * - Base address of 0xFE000000 + * - 32 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR0_PRELIM ((CFG_FLASH0_BASE & BRx_BA_MSK) |\ + BRx_PS_32 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR0 is configured as follows: + * + * - 32 MB + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 5 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +#define CFG_OR0_PRELIM (MEG_TO_AM(CFG_FLASH0_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) + +/*----------------------------------------------------------------------- + * BR2,BR3 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR2,OR3 - Option Register + * Ref: Section 10.3.2 on page 10-16 + *----------------------------------------------------------------------- + */ + +/* + * Bank 2,3 - 128 MB SDRAM DIMM + */ + +/* With a 128 MB DIMM, the BR2 is configured as follows: + * + * - Base address of 0x00000000/0x08000000 + * - 64 bit port size (60x bus only) + * - Data errors checking is disabled + * - Read and write access + * - SDRAM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR2_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +#define CFG_BR3_PRELIM ((CFG_SDRAM1_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +/* With a 128 MB DIMM, the OR2 is configured as follows: + * + * - 128 MB + * - 4 internal banks per device + * - Row start address bit is A8 with PSDMR[PBI] = 0 + * - 13 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ + +#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\ + ORxS_BPD_4 |\ + ORxS_ROWST_PBI0_A7 |\ + ORxS_NUMR_13) + +#define CFG_OR3_PRELIM (MEG_TO_AM(CFG_SDRAM1_SIZE) |\ + ORxS_BPD_4 |\ + ORxS_ROWST_PBI0_A7 |\ + ORxS_NUMR_13) + + +/*----------------------------------------------------------------------- + * PSDMR - 60x Bus SDRAM Mode Register + * Ref: Section 10.3.3 on page 10-21 + *----------------------------------------------------------------------- + */ + +/* With a 128 MB DIMM, the PSDMR is configured as follows: + * + * - Page Based Interleaving, + * - Refresh Enable, + * - Normal Operation + * - Address Multiplexing where A5 is output on A14 pin + * (A6 on A15, and so on), + * - use address pins A13-A15 as bank select, + * - A9 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 3 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - External Address Multiplexing enabled + * - CAS Latency is 2. + */ +#define CFG_PSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A13_A15 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_EAMUX |\ + PSDMR_CL_2) + + +#define CFG_PSRT 0x0e +#define CFG_MPTPR MPTPR_PTP_DIV32 + + +/*----------------------------------------------------------------------- + * BR4 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR4 - Option Register + * Ref: Section 10.3.2 on page 10-16 + *----------------------------------------------------------------------- + */ + +/* + * Bank 4 - On board SDRAM + * + */ +/* With 16 MB of onboard SDRAM BR4 is configured as follows + * + * - Base address 0x38000000 + * - 32 bit port size + * - Data error checking disabled + * - Read/Write access + * - SDRAM local bus + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + * + */ + +#define CFG_BR4_PRELIM ((CFG_SDRAM2_BASE & BRx_BA_MSK) |\ + BRx_PS_32 |\ + BRx_DECC_NONE |\ + BRx_MS_SDRAM_L |\ + BRx_V) + +/* + * With 16MB SDRAM, OR4 is configured as follows + * - 4 internal banks per device + * - Row start address bit is A10 with LSDMR[PBI] = 0 + * - 12 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ + +#define CFG_OR4_PRELIM (MEG_TO_AM(CFG_SDRAM2_SIZE) |\ + ORxS_BPD_4 |\ + ORxS_ROWST_PBI0_A10 |\ + ORxS_NUMR_12) + + +/*----------------------------------------------------------------------- + * LSDMR - Local Bus SDRAM Mode Register + * Ref: Section 10.3.4 on page 10-24 + *----------------------------------------------------------------------- + */ + +/* With a 16 MB onboard SDRAM, the LSDMR is configured as follows: + * + * - Page Based Interleaving, + * - Refresh Enable, + * - Normal Operation + * - Address Multiplexing where A5 is output on A13 pin + * (A6 on A15, and so on), + * - use address pins A15-A17 as bank select, + * - A11 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 2 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - SDRAM burst length is 8 + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - External Address Multiplexing disabled + * - CAS Latency is 2. + */ +#define CFG_LSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A13_IS_A5 |\ + PSDMR_BSMA_A15_A17 |\ + PSDMR_SDA10_PBI0_A11 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_2W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_BL |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) + +#define CFG_LSRT 0x0e + +/*----------------------------------------------------------------------- + * BR5 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR5 - Option Register + * Ref: Section 10.3.2 on page 10-16 + *----------------------------------------------------------------------- + */ + +/* + * Bank 5 EEProm and Mailbox + * + * The EEPROM and mailbox live on the same chip select. + * the eeprom is selected if the MSb of the address is set and the mailbox is + * selected if the MSb of the address is clear. + * + */ + +/* BR5 is configured as follows: + * + * - Base address of 0x32000000/0xF2000000 + * - 8 bit + * - Data error checking disabled + * - Read/Write access + * - GPCM 60x Bus + * - SDRAM local bus + * - No data pipelining is done + * - Valid + */ + +#define CFG_BR5_PRELIM ((CFG_MAILBOX_BASE & BRx_BA_MSK) |\ + BRx_PS_8 |\ + BRx_DECC_NONE |\ + BRx_MS_GPCM_P |\ + BRx_V) +/* OR5 is configured as follows + * - buffer control enabled + * - chip select negated normally + * - CS output 1/2 clock after address + * - 15 wait states + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ + +#define CFG_OR5_PRELIM ((P2SZ_TO_AM(CFG_MAILBOX_SIZE) & ~0x80000000) |\ + ORxG_ACS_DIV2 |\ + ORxG_SCY_15_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) + +/*----------------------------------------------------------------------- + * BR6 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR6 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 6 - I/O select + * + */ + +/* BR6 is configured as follows: + * + * - Base address of 0xE0000000 + * - 16 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR6_PRELIM ((CFG_IOSELECT_BASE & BRx_BA_MSK) |\ + BRx_PS_16 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR6 is configured as follows + * - buffer control enabled + * - chip select negated normally + * - CS output 1/2 clock after address + * - 15 wait states + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ + +#define CFG_OR6_PRELIM (MEG_TO_AM(CFG_IOSELECT_SIZE) |\ + ORxG_ACS_DIV2 |\ + ORxG_SCY_15_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) + + +/*----------------------------------------------------------------------- + * BR7 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR7 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 7 - LEDs and switches + * + * LEDs are at 0x00001 (write only) + * switches are at 0x00001 (read only) + */ +#ifdef CFG_LED_BASE + +/* BR7 is configured as follows: + * + * - Base address of 0xA0000000 + * - 8 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR7_PRELIM ((CFG_LED_BASE & BRx_BA_MSK) |\ + BRx_PS_8 |\ + BRx_DECC_NONE |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR7 is configured as follows: + * + * - 1 byte + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 15 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +#define CFG_OR7_PRELIM (ORxG_AM_MSK |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_15_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) +#endif /* CFG_LED_BASE */ + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ diff --git a/include/configs/sacsng.h b/include/configs/sacsng.h new file mode 100644 index 0000000..92cdcf0 --- /dev/null +++ b/include/configs/sacsng.h @@ -0,0 +1,1000 @@ +/* + * (C) Copyright 2000 + * Murray Jensen <Murray.Jensen@cmst.csiro.au> + * + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * Configuration settings for the WindRiver SBC8260 board. + * See http://www.windriver.com/products/html/sbc8260.html + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* Enable debug prints */ +#undef DEBUG /* General debug */ +#undef DEBUG_BOOTP_EXT /* Debug received vendor fields */ + +/***************************************************************************** + * + * These settings must match the way _your_ board is set up + * + *****************************************************************************/ + +/* What is the oscillator's (UX2) frequency in Hz? */ +#define CONFIG_8260_CLKIN 66666600 + +/*----------------------------------------------------------------------- + * MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual + *----------------------------------------------------------------------- + * What should MODCK_H be? It is dependent on the oscillator + * frequency, MODCK[1-3], and desired CPM and core frequencies. + * Here are some example values (all frequencies are in MHz): + * + * MODCK_H MODCK[1-3] Osc CPM Core S2-6 S2-7 S2-8 + * ------- ---------- --- --- ---- ----- ----- ----- + * 0x1 0x5 33 100 133 Open Close Open + * 0x1 0x6 33 100 166 Open Open Close + * 0x1 0x7 33 100 200 Open Open Open + * + * 0x2 0x2 33 133 133 Close Open Close + * 0x2 0x3 33 133 166 Close Open Open + * 0x2 0x4 33 133 200 Open Close Close + * 0x2 0x5 33 133 233 Open Close Open + * 0x2 0x6 33 133 266 Open Open Close + * + * 0x5 0x5 66 133 133 Open Close Open + * 0x5 0x6 66 133 166 Open Open Close + * 0x5 0x7 66 133 200 Open Open Open + * 0x6 0x0 66 133 233 Close Close Close + * 0x6 0x1 66 133 266 Close Close Open + * 0x6 0x2 66 133 300 Close Open Close + */ +#define CFG_SBC_MODCK_H 0x05 + +/* Define this if you want to boot from 0x00000100. If you don't define + * this, you will need to program the bootloader to 0xfff00000, and + * get the hardware reset config words at 0xfe000000. The simplest + * way to do that is to program the bootloader at both addresses. + * It is suggested that you just let U-Boot live at 0x00000000. + */ +#define CFG_SBC_BOOT_LOW 1 + +/* What should the base address of the main FLASH be and how big is + * it (in MBytes)? This must contain TEXT_BASE from board/sacsng/config.mk + * The main FLASH is whichever is connected to *CS0. + */ +#define CFG_FLASH0_BASE 0x40000000 +#define CFG_FLASH0_SIZE 2 + +/* What should the base address of the secondary FLASH be and how big + * is it (in Mbytes)? The secondary FLASH is whichever is connected + * to *CS6. + */ +#define CFG_FLASH1_BASE 0x60000000 +#define CFG_FLASH1_SIZE 2 + +/* Define CONFIG_VERY_BIG_RAM to allow use of SDRAMs larger than 256MBytes + */ +#define CONFIG_VERY_BIG_RAM 1 + +/* What should be the base address of SDRAM DIMM and how big is + * it (in Mbytes)? This will normally auto-configure via the SPD. +*/ +#define CFG_SDRAM0_BASE 0x00000000 +#define CFG_SDRAM0_SIZE 64 + +/* + * Memory map example with 64 MB DIMM: + * + * 0x0000 0000 Exception Vector code, 8k + * : + * 0x0000 1FFF + * 0x0000 2000 Free for Application Use + * : + * : + * + * : + * : + * 0x03F5 FF30 Monitor Stack (Growing downward) + * Monitor Stack Buffer (0x80) + * 0x03F5 FFB0 Board Info Data + * 0x03F6 0000 Malloc Arena + * : CFG_ENV_SECT_SIZE, 16k + * : CFG_MALLOC_LEN, 128k + * 0x03FC 0000 RAM Copy of Monitor Code + * : CFG_MONITOR_LEN, 256k + * 0x03FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1 + */ + +#define CONFIG_POST (CFG_POST_MEMORY | \ + CFG_POST_CPU) + + +/* + * select serial console configuration + * + * if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then + * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4 + * for SCC). + * + * if CONFIG_CONS_NONE is defined, then the serial console routines must + * defined elsewhere. + */ +#define CONFIG_CONS_ON_SMC 1 /* define if console on SMC */ +#undef CONFIG_CONS_ON_SCC /* define if console on SCC */ +#undef CONFIG_CONS_NONE /* define if console on neither */ +#define CONFIG_CONS_INDEX 1 /* which SMC/SCC channel for console */ + +/* + * select ethernet configuration + * + * if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then + * CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3 + * for FCC) + * + * if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be + * defined elsewhere (as for the console), or CFG_CMD_NET must be removed + * from CONFIG_COMMANDS to remove support for networking. + */ + +#undef CONFIG_ETHER_ON_SCC +#define CONFIG_ETHER_ON_FCC +#undef CONFIG_ETHER_NONE /* define if ethernet on neither */ + +#ifdef CONFIG_ETHER_ON_SCC +#define CONFIG_ETHER_INDEX 1 /* which SCC/FCC channel for ethernet */ +#endif /* CONFIG_ETHER_ON_SCC */ + +#ifdef CONFIG_ETHER_ON_FCC +#define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */ +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +/* + * Port pins used for bit-banged MII communictions (if applicable). + */ + +#define MDIO_PORT 2 /* Port A=0, B=1, C=2, D=3 */ +#define MDIO_ACTIVE (iop->pdir |= 0x40000000) +#define MDIO_TRISTATE (iop->pdir &= ~0x40000000) +#define MDIO_READ ((iop->pdat & 0x40000000) != 0) + +#define MDIO(bit) if(bit) iop->pdat |= 0x40000000; \ + else iop->pdat &= ~0x40000000 + +#define MDC(bit) if(bit) iop->pdat |= 0x80000000; \ + else iop->pdat &= ~0x80000000 + +#define MIIDELAY udelay(50) +#endif /* CONFIG_ETHER_ON_FCC */ + +#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1) + +/* + * - RX clk is CLK11 + * - TX clk is CLK12 + */ +# define CFG_CMXSCR_VALUE (CMXSCR_RS1CS_CLK11 | CMXSCR_TS1CS_CLK12) + +#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2) + +/* + * - Rx-CLK is CLK13 + * - Tx-CLK is CLK14 + * - Select bus for bd/buffers (see 28-13) + * - Enable Full Duplex in FSMR + */ +# define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK) +# define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14) +# define CFG_CPMFCR_RAMTYPE 0 +# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB) + +#endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */ + +#define CONFIG_SHOW_BOOT_PROGRESS 1 /* boot progress enabled */ + +/* + * Configure for RAM tests. + */ +#undef CFG_DRAM_TEST /* calls other tests in board.c */ + + +/* + * Status LED for power up status feedback. + */ +#define CONFIG_STATUS_LED 1 /* Status LED enabled */ + +#define STATUS_LED_PAR im_ioport.iop_ppara +#define STATUS_LED_DIR im_ioport.iop_pdira +#define STATUS_LED_ODR im_ioport.iop_podra +#define STATUS_LED_DAT im_ioport.iop_pdata + +#define STATUS_LED_BIT 0x00000800 /* LED 0 is on PA.20 */ +#define STATUS_LED_PERIOD (CFG_HZ) +#define STATUS_LED_STATE STATUS_LED_OFF +#define STATUS_LED_BIT1 0x00001000 /* LED 1 is on PA.19 */ +#define STATUS_LED_PERIOD1 (CFG_HZ) +#define STATUS_LED_STATE1 STATUS_LED_OFF +#define STATUS_LED_BIT2 0x00002000 /* LED 2 is on PA.18 */ +#define STATUS_LED_PERIOD2 (CFG_HZ/2) +#define STATUS_LED_STATE2 STATUS_LED_ON + +#define STATUS_LED_ACTIVE 0 /* LED on for bit == 0 */ + +#define STATUS_LED_YELLOW 0 +#define STATUS_LED_GREEN 1 +#define STATUS_LED_RED 2 +#define STATUS_LED_BOOT 1 + + +/* + * select SPI support configuration + */ +#define CONFIG_SOFT_SPI /* enable SPI driver */ + +/* + * Software (bit-bang) SPI driver configuration + */ +#ifdef CONFIG_SOFT_SPI + +/* + * Software (bit-bang) SPI driver configuration + */ +#define I2C_SCLK 0x00002000 /* PD 18: Shift clock */ +#define I2C_MOSI 0x00004000 /* PD 17: Master Out, Slave In */ +#define I2C_MISO 0x00008000 /* PD 16: Master In, Slave Out */ + +#undef SPI_INIT /* no port initialization needed */ +#define SPI_READ ((immr->im_ioport.iop_pdatd & I2C_MISO) != 0) +#define SPI_SDA(bit) if(bit) immr->im_ioport.iop_pdatd |= I2C_MOSI; \ + else immr->im_ioport.iop_pdatd &= ~I2C_MOSI +#define SPI_SCL(bit) if(bit) immr->im_ioport.iop_pdatd |= I2C_SCLK; \ + else immr->im_ioport.iop_pdatd &= ~I2C_SCLK +#define SPI_DELAY /*udelay(1)*/ /* 1/2 SPI clock duration */ +#endif /* CONFIG_SOFT_SPI */ + + +/* + * select I2C support configuration + * + * Supported configurations are {none, software, hardware} drivers. + * If the software driver is chosen, there are some additional + * configuration items that the driver uses to drive the port pins. + */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ +#ifdef CONFIG_SOFT_I2C +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_DELAY udelay(20) /* 1/4 I2C clock duration */ +#endif /* CONFIG_SOFT_I2C */ + +/* Define this to reserve an entire FLASH sector for + * environment variables. Otherwise, the environment will be + * put in the same sector as U-Boot, and changing variables + * will erase U-Boot temporarily + */ +#define CFG_ENV_IN_OWN_SECT 1 + +/* Define this to contain any number of null terminated strings that + * will be part of the default enviroment compiled into the boot image. + */ +#define CONFIG_EXTRA_ENV_SETTINGS \ +"serverip=192.168.123.201\0" \ +"ipaddr=192.168.123.203\0" \ +"checkhostname=VR8500\0" \ +"reprog="\ + "tftpboot 0x140000 /bdi2000/u-boot.bin; " \ + "protect off 60000000 6003FFFF; " \ + "erase 60000000 6003FFFF; " \ + "cp.b 140000 60000000 $(filesize); " \ + "protect on 60000000 6003FFFF\0" \ +"copyenv="\ + "protect off 60040000 6004FFFF; " \ + "erase 60040000 6004FFFF; " \ + "cp.b 40040000 60040000 10000; " \ + "protect on 60040000 6004FFFF\0" \ +"copyprog="\ + "protect off 60000000 6003FFFF; " \ + "erase 60000000 6003FFFF; " \ + "cp.b 40000000 60000000 40000; " \ + "protect on 60000000 6003FFFF\0" \ +"zapenv="\ + "protect off 40040000 4004FFFF; " \ + "erase 40040000 4004FFFF; " \ + "protect on 40040000 4004FFFF\0" \ +"zapotherenv="\ + "protect off 60040000 6004FFFF; " \ + "erase 60040000 6004FFFF; " \ + "protect on 60040000 6004FFFF\0" \ +"root-on-initrd="\ + "setenv bootcmd "\ + "version\\;" \ + "echo\\;" \ + "bootp\\;" \ + "setenv bootargs root=/dev/ram0 rw quiet " \ + "ip=\\$(ipaddr):\\$(serverip):\\$(gatewayip):\\$(netmask):\\$(hostname)::off\\;" \ + "run boot-hook\\;" \ + "bootm\0" \ +"root-on-initrd-debug="\ + "setenv bootcmd "\ + "version\\;" \ + "echo\\;" \ + "bootp\\;" \ + "setenv bootargs root=/dev/ram0 rw debug " \ + "ip=\\$(ipaddr):\\$(serverip):\\$(gatewayip):\\$(netmask):\\$(hostname)::off\\;" \ + "run debug-hook\\;" \ + "run boot-hook\\;" \ + "bootm\0" \ +"root-on-nfs="\ + "setenv bootcmd "\ + "version\\;" \ + "echo\\;" \ + "bootp\\;" \ + "setenv bootargs root=/dev/nfs rw quiet " \ + "nfsroot=\\$(serverip):\\$(rootpath) " \ + "ip=\\$(ipaddr):\\$(serverip):\\$(gatewayip):\\$(netmask):\\$(hostname)::off\\;" \ + "run boot-hook\\;" \ + "bootm\0" \ +"root-on-nfs-debug="\ + "setenv bootcmd "\ + "version\\;" \ + "echo\\;" \ + "bootp\\;" \ + "setenv bootargs root=/dev/nfs rw debug " \ + "nfsroot=\\$(serverip):\\$(rootpath) " \ + "ip=\\$(ipaddr):\\$(serverip):\\$(gatewayip):\\$(netmask):\\$(hostname)::off\\;" \ + "run debug-hook\\;" \ + "run boot-hook\\;" \ + "bootm\0" \ +"debug-checkout="\ + "setenv checkhostname;" \ + "setenv ethaddr 00:09:70:00:00:01;" \ + "bootp;" \ + "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) debug " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "run debug-hook;" \ + "run boot-hook;" \ + "bootm\0" \ +"debug-hook="\ + "echo ipaddr $(ipaddr);" \ + "echo serverip $(serverip);" \ + "echo gatewayip $(gatewayip);" \ + "echo netmask $(netmask);" \ + "echo hostname $(hostname)\0" \ +"ana=run adc ; run dac\0" \ +"adc=run adc-12 ; run adc-34\0" \ +"adc-12=echo ### ADC-12 ; imd.b e 81 e\0" \ +"adc-34=echo ### ADC-34 ; imd.b f 81 e\0" \ +"dac=echo ### DAC ; imd.b 11 81 5\0" \ +"boot-hook=run ana\0" + +/* What should the console's baud rate be? */ +#define CONFIG_BAUDRATE 9600 + +/* Ethernet MAC address */ +#define CONFIG_ETHADDR 00:09:70:00:00:00 + +/* The default Ethernet MAC address can be overwritten just once */ +#ifdef CONFIG_ETHADDR +#define CONFIG_OVERWRITE_ETHADDR_ONCE 1 +#endif + +/* + * Define this to do some miscellaneous board-specific initialization. + */ +#define CONFIG_MISC_INIT_R + +/* Set to a positive value to delay for running BOOTCOMMAND */ +#define CONFIG_BOOTDELAY 1 /* autoboot after 1 second */ + +/* Be selective on what keys can delay or stop the autoboot process + * To stop use: " " + */ +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT "Autobooting...\n" +#define CONFIG_AUTOBOOT_STOP_STR " " +#undef CONFIG_AUTOBOOT_DELAY_STR +#define CONFIG_ZERO_BOOTDELAY_CHECK +#define DEBUG_BOOTKEYS 0 + +/* Define a command string that is automatically executed when no character + * is read on the console interface withing "Boot Delay" after reset. + */ +#define CONFIG_BOOT_ROOT_INITRD 0 /* Use ram disk for the root file system */ +#define CONFIG_BOOT_ROOT_NFS 1 /* Use a NFS mounted root file system */ + +#if CONFIG_BOOT_ROOT_INITRD +#define CONFIG_BOOTCOMMAND \ + "version;" \ + "echo;" \ + "bootp;" \ + "setenv bootargs root=/dev/ram0 rw quiet " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "run boot-hook;" \ + "bootm" +#endif /* CONFIG_BOOT_ROOT_INITRD */ + +#if CONFIG_BOOT_ROOT_NFS +#define CONFIG_BOOTCOMMAND \ + "version;" \ + "echo;" \ + "bootp;" \ + "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) quiet " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "run boot-hook;" \ + "bootm" +#endif /* CONFIG_BOOT_ROOT_NFS */ + +#define CONFIG_BOOTP_RANDOM_DELAY /* Randomize the BOOTP retry delay */ + +#define CONFIG_BOOTP_RETRY_COUNT 0x40000000 /* # of timeouts before giving up */ + +/* Add support for a few extra bootp options like: + * - File size + * - DNS + */ +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \ + CONFIG_BOOTP_BOOTFILESIZE | \ + CONFIG_BOOTP_DNS) + +/* undef this to save memory */ +#define CFG_LONGHELP + +/* Monitor Command Prompt */ +#define CFG_PROMPT "=> " + +#undef CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* What U-Boot subsytems do you want enabled? */ +#ifdef CONFIG_ETHER_ON_FCC +# define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_ELF | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_I2C | \ + CFG_CMD_SPI | \ + CFG_CMD_SDRAM | \ + CFG_CMD_REGINFO | \ + CFG_CMD_IMMAP | \ + CFG_CMD_MII ) +#else +# define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_ELF | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_I2C | \ + CFG_CMD_SPI | \ + CFG_CMD_SDRAM | \ + CFG_CMD_REGINFO | \ + CFG_CMD_IMMAP ) +#endif /* CONFIG_ETHER_ON_FCC */ + +/* Where do the internal registers live? */ +#define CFG_IMMR 0xF0000000 + +/***************************************************************************** + * + * You should not have to modify any of the following settings + * + *****************************************************************************/ + +#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */ +#define CONFIG_SBC8260 1 /* on an EST SBC8260 Board */ +#define CONFIG_SACSng 1 /* munged for the SACSng */ + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +/* + * Miscellaneous configurable options + */ +#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 + +/* Print Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT)+16) + +#define CFG_MAXARGS 32 /* max number of command args */ + +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_LOAD_ADDR 0x400000 /* default load address */ +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CFG_MEMTEST_START 0x2000 /* memtest works from the end of */ + /* the exception vector table */ + /* to the end of the DRAM */ + /* less monitor and malloc area */ +#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */ +#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \ + + CFG_MALLOC_LEN \ + + CFG_ENV_SECT_SIZE \ + + CFG_STACK_USAGE ) + +#define CFG_MEMTEST_END ( CFG_SDRAM_SIZE * 1024 * 1024 \ + - CFG_MEM_END_USAGE ) + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ + +#define CFG_FLASH_BASE CFG_FLASH0_BASE +#define CFG_FLASH_SIZE CFG_FLASH0_SIZE +#define CFG_SDRAM_BASE CFG_SDRAM0_BASE +#define CFG_SDRAM_SIZE CFG_SDRAM0_SIZE + +/*----------------------------------------------------------------------- + * Hard Reset Configuration Words + */ +#if defined(CFG_SBC_BOOT_LOW) +# define CFG_SBC_HRCW_BOOT_FLAGS (HRCW_CIP | HRCW_BMS) +#else +# define CFG_SBC_HRCW_BOOT_FLAGS (0) +#endif /* defined(CFG_SBC_BOOT_LOW) */ + +/* get the HRCW ISB field from CFG_IMMR */ +#define CFG_SBC_HRCW_IMMR ( ((CFG_IMMR & 0x10000000) >> 10) | \ + ((CFG_IMMR & 0x01000000) >> 7) | \ + ((CFG_IMMR & 0x00100000) >> 4) ) + +#define CFG_HRCW_MASTER ( HRCW_BPS10 | \ + HRCW_DPPC11 | \ + CFG_SBC_HRCW_IMMR | \ + HRCW_MMR00 | \ + HRCW_LBPC11 | \ + HRCW_APPC10 | \ + HRCW_CS10PC00 | \ + (CFG_SBC_MODCK_H & HRCW_MODCK_H1111) | \ + CFG_SBC_HRCW_BOOT_FLAGS ) + +/* no slaves */ +#define CFG_HRCW_SLAVE1 0 +#define CFG_HRCW_SLAVE2 0 +#define CFG_HRCW_SLAVE3 0 +#define CFG_HRCW_SLAVE4 0 +#define CFG_HRCW_SLAVE5 0 +#define CFG_HRCW_SLAVE6 0 +#define CFG_HRCW_SLAVE7 0 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + * Note also that the logic that sets CFG_RAMBOOT is platform dependent. + */ +#define CFG_MONITOR_BASE CFG_FLASH0_BASE + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +# define CFG_RAMBOOT +#endif + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* 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 and environment organization + */ + +#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ +#undef CFG_FLASH_PROTECTION /* use hardware protection */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT (64+4) /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 8000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 1 /* Timeout for Flash Write (in ms) */ + +#ifndef CFG_RAMBOOT +# define CFG_ENV_IS_IN_FLASH 1 + +# ifdef CFG_ENV_IN_OWN_SECT +# define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) +# define CFG_ENV_SECT_SIZE 0x10000 +# else +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_MONITOR_LEN - CFG_ENV_SECT_SIZE) +# define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ +# define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sect real size */ +# endif /* CFG_ENV_IN_OWN_SECT */ + +#else +# define CFG_ENV_IS_IN_NVRAM 1 +# define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) +# define CFG_ENV_SIZE 0x200 +#endif /* CFG_RAMBOOT */ + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * HIDx - Hardware Implementation-dependent Registers 2-11 + *----------------------------------------------------------------------- + * HID0 also contains cache control - initially enable both caches and + * invalidate contents, then the final state leaves only the instruction + * cache enabled. Note that Power-On and Hard reset invalidate the caches, + * but Soft reset does not. + * + * HID1 has only read-only information - nothing to set. + */ +#define CFG_HID0_INIT (HID0_ICE |\ + HID0_DCE |\ + HID0_ICFI |\ + HID0_DCI |\ + HID0_IFEM |\ + HID0_ABE) + +#define CFG_HID0_FINAL (HID0_ICE |\ + HID0_IFEM |\ + HID0_ABE |\ + HID0_EMCP) +#define CFG_HID2 0 + +/*----------------------------------------------------------------------- + * RMR - Reset Mode Register + *----------------------------------------------------------------------- + */ +#define CFG_RMR 0 + +/*----------------------------------------------------------------------- + * BCR - Bus Configuration 4-25 + *----------------------------------------------------------------------- + */ +#define CFG_BCR (BCR_ETM) + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration 4-31 + *----------------------------------------------------------------------- + */ + +#define CFG_SIUMCR (SIUMCR_DPPC11 |\ + SIUMCR_L2CPC00 |\ + SIUMCR_APPC10 |\ + SIUMCR_MMR00) + + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable + */ +#define CFG_SYPCR (SYPCR_SWTC |\ + SYPCR_BMT |\ + SYPCR_PBME |\ + SYPCR_LBME |\ + SYPCR_SWRI |\ + SYPCR_SWP) + +/*----------------------------------------------------------------------- + * TMCNTSC - Time Counter Status and Control 4-40 + *----------------------------------------------------------------------- + * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk, + * and enable Time Counter + */ +#define CFG_TMCNTSC (TMCNTSC_SEC |\ + TMCNTSC_ALR |\ + TMCNTSC_TCF |\ + TMCNTSC_TCE) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 4-42 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable + * Periodic timer + */ +#define CFG_PISCR (PISCR_PS |\ + PISCR_PTF |\ + PISCR_PTE) + +/*----------------------------------------------------------------------- + * SCCR - System Clock Control 9-8 + *----------------------------------------------------------------------- + */ +#define CFG_SCCR 0 + +/*----------------------------------------------------------------------- + * RCCR - RISC Controller Configuration 13-7 + *----------------------------------------------------------------------- + */ +#define CFG_RCCR 0 + +/* + * Initialize Memory Controller: + * + * Bank Bus Machine PortSz Device + * ---- --- ------- ------ ------ + * 0 60x GPCM 16 bit FLASH (primary flash - 2MB) + * 1 60x GPCM -- bit (Unused) + * 2 60x SDRAM 64 bit SDRAM (DIMM) + * 3 60x SDRAM 64 bit SDRAM (DIMM) + * 4 60x GPCM -- bit (Unused) + * 5 60x GPCM -- bit (Unused) + * 6 60x GPCM 16 bit FLASH (secondary flash - 2MB) + */ + +/*----------------------------------------------------------------------- + * BR0,BR1 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR0,OR1 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 0 - Primary FLASH + */ + +/* BR0 is configured as follows: + * + * - Base address of 0x40000000 + * - 16 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR0_PRELIM ((CFG_FLASH0_BASE & BRx_BA_MSK) |\ + BRx_PS_16 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR0 is configured as follows: + * + * - 4 MB + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 5 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +#define CFG_OR0_PRELIM (MEG_TO_AM(CFG_FLASH0_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) + +/*----------------------------------------------------------------------- + * BR2,BR3 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR2,OR3 - Option Register + * Ref: Section 10.3.2 on page 10-16 + *----------------------------------------------------------------------- + */ + +/* Bank 2,3 - SDRAM DIMM + */ + +/* The BR2 is configured as follows: + * + * - Base address of 0x00000000 + * - 64 bit port size (60x bus only) + * - Data errors checking is disabled + * - Read and write access + * - SDRAM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR2_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +#define CFG_BR3_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +/* With a 64 MB DIMM, the OR2 is configured as follows: + * + * - 64 MB + * - 4 internal banks per device + * - Row start address bit is A8 with PSDMR[PBI] = 0 + * - 12 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ +#if (CFG_SDRAM0_SIZE == 64) +#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\ + ORxS_BPD_4 |\ + ORxS_ROWST_PBI0_A8 |\ + ORxS_NUMR_12) +#else +#error "INVALID SDRAM CONFIGURATION" +#endif + +/*----------------------------------------------------------------------- + * PSDMR - 60x Bus SDRAM Mode Register + * Ref: Section 10.3.3 on page 10-21 + *----------------------------------------------------------------------- + */ + +/* Address that the DIMM SPD memory lives at. + */ +#define SDRAM_SPD_ADDR 0x50 + +#if (CFG_SDRAM0_SIZE == 64) +/* With a 64 MB DIMM, the PSDMR is configured as follows: + * + * - Bank Based Interleaving, + * - Refresh Enable, + * - Address Multiplexing where A5 is output on A14 pin + * (A6 on A15, and so on), + * - use address pins A14-A16 as bank select, + * - A9 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 3 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - CAS Latency is 2. + */ +#define CFG_PSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A14_A16 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) +#else +#error "INVALID SDRAM CONFIGURATION" +#endif + +/* + * Shoot for approximately 1MHz on the prescaler. + */ +#if (CONFIG_8260_CLKIN >= (60 * 1000 * 1000)) +#define CFG_MPTPR MPTPR_PTP_DIV64 +#elif (CONFIG_8260_CLKIN >= (30 * 1000 * 1000)) +#define CFG_MPTPR MPTPR_PTP_DIV32 +#else +#warning "Unconfigured bus clock freq: check CFG_MPTPR and CFG_PSRT are OK" +#define CFG_MPTPR MPTPR_PTP_DIV32 +#endif +#define CFG_PSRT 14 + + +/*----------------------------------------------------------------------- + * BR6 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR6 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 6 - Secondary FLASH + * + * The secondary FLASH is connected to *CS6 + */ +#if (defined(CFG_FLASH1_BASE) && defined(CFG_FLASH1_SIZE)) + +/* BR6 is configured as follows: + * + * - Base address of 0x60000000 + * - 16 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +# define CFG_BR6_PRELIM ((CFG_FLASH1_BASE & BRx_BA_MSK) |\ + BRx_PS_16 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR6 is configured as follows: + * + * - 2 MB + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 5 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +# define CFG_OR6_PRELIM (MEG_TO_AM(CFG_FLASH1_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) +#endif /* (defined(CFG_FLASH1_BASE) && defined(CFG_FLASH1_SIZE)) */ + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ diff --git a/include/configs/sbc8260.h b/include/configs/sbc8260.h new file mode 100644 index 0000000..b89f503 --- /dev/null +++ b/include/configs/sbc8260.h @@ -0,0 +1,980 @@ +/* + * (C) Copyright 2000 + * Murray Jensen <Murray.Jensen@cmst.csiro.au> + * + * (C) Copyright 2000 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2001 + * Advent Networks, Inc. <http://www.adventnetworks.com> + * Jay Monkman <jtm@smoothsmoothie.com> + * + * Configuration settings for the WindRiver SBC8260 board. + * See http://www.windriver.com/products/html/sbc8260.html + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* Enable debug prints */ +#undef DEBUG /* General debug */ +#undef DEBUG_BOOTP_EXT /* Debug received vendor fields */ + +/***************************************************************************** + * + * These settings must match the way _your_ board is set up + * + *****************************************************************************/ + +/* What is the oscillator's (UX2) frequency in Hz? */ +#define CONFIG_8260_CLKIN (66 * 1000 * 1000) + +/*----------------------------------------------------------------------- + * MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual + *----------------------------------------------------------------------- + * What should MODCK_H be? It is dependent on the oscillator + * frequency, MODCK[1-3], and desired CPM and core frequencies. + * Here are some example values (all frequencies are in MHz): + * + * MODCK_H MODCK[1-3] Osc CPM Core S2-6 S2-7 S2-8 + * ------- ---------- --- --- ---- ----- ----- ----- + * 0x1 0x5 33 100 133 Open Close Open + * 0x1 0x6 33 100 166 Open Open Close + * 0x1 0x7 33 100 200 Open Open Open + * + * 0x2 0x2 33 133 133 Close Open Close + * 0x2 0x3 33 133 166 Close Open Open + * 0x2 0x4 33 133 200 Open Close Close + * 0x2 0x5 33 133 233 Open Close Open + * 0x2 0x6 33 133 266 Open Open Close + * + * 0x5 0x5 66 133 133 Open Close Open + * 0x5 0x6 66 133 166 Open Open Close + * 0x5 0x7 66 133 200 Open Open Open + * 0x6 0x0 66 133 233 Close Close Close + * 0x6 0x1 66 133 266 Close Close Open + * 0x6 0x2 66 133 300 Close Open Close + */ +#define CFG_SBC_MODCK_H 0x05 + +/* Define this if you want to boot from 0x00000100. If you don't define + * this, you will need to program the bootloader to 0xfff00000, and + * get the hardware reset config words at 0xfe000000. The simplest + * way to do that is to program the bootloader at both addresses. + * It is suggested that you just let U-Boot live at 0x00000000. + */ +#define CFG_SBC_BOOT_LOW 1 + +/* What should the base address of the main FLASH be and how big is + * it (in MBytes)? This must contain TEXT_BASE from board/sbc8260/config.mk + * The main FLASH is whichever is connected to *CS0. U-Boot expects + * this to be the SIMM. + */ +#define CFG_FLASH0_BASE 0x40000000 +#define CFG_FLASH0_SIZE 4 + +/* What should the base address of the secondary FLASH be and how big + * is it (in Mbytes)? The secondary FLASH is whichever is connected + * to *CS6. U-Boot expects this to be the on board FLASH. If you don't + * want it enabled, don't define these constants. + */ +#define CFG_FLASH1_BASE 0x60000000 +#define CFG_FLASH1_SIZE 2 + +/* What should be the base address of SDRAM DIMM and how big is + * it (in Mbytes)? +*/ +#define CFG_SDRAM0_BASE 0x00000000 +#define CFG_SDRAM0_SIZE 64 + +/* What should be the base address of the LEDs and switch S0? + * If you don't want them enabled, don't define this. + */ +#define CFG_LED_BASE 0xa0000000 + + +/* + * SBC8260 with 16 MB DIMM: + * + * 0x0000 0000 Exception Vector code, 8k + * : + * 0x0000 1FFF + * 0x0000 2000 Free for Application Use + * : + * : + * + * : + * : + * 0x00F5 FF30 Monitor Stack (Growing downward) + * Monitor Stack Buffer (0x80) + * 0x00F5 FFB0 Board Info Data + * 0x00F6 0000 Malloc Arena + * : CFG_ENV_SECT_SIZE, 256k + * : CFG_MALLOC_LEN, 128k + * 0x00FC 0000 RAM Copy of Monitor Code + * : CFG_MONITOR_LEN, 256k + * 0x00FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1 + */ + +/* + * SBC8260 with 64 MB DIMM: + * + * 0x0000 0000 Exception Vector code, 8k + * : + * 0x0000 1FFF + * 0x0000 2000 Free for Application Use + * : + * : + * + * : + * : + * 0x03F5 FF30 Monitor Stack (Growing downward) + * Monitor Stack Buffer (0x80) + * 0x03F5 FFB0 Board Info Data + * 0x03F6 0000 Malloc Arena + * : CFG_ENV_SECT_SIZE, 256k + * : CFG_MALLOC_LEN, 128k + * 0x03FC 0000 RAM Copy of Monitor Code + * : CFG_MONITOR_LEN, 256k + * 0x03FF FFFF [End of RAM], CFG_SDRAM_SIZE - 1 + */ + + +/* + * select serial console configuration + * + * if either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then + * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4 + * for SCC). + * + * if CONFIG_CONS_NONE is defined, then the serial console routines must + * defined elsewhere. + */ +#define CONFIG_CONS_ON_SMC 1 /* define if console on SMC */ +#undef CONFIG_CONS_ON_SCC /* define if console on SCC */ +#undef CONFIG_CONS_NONE /* define if console on neither */ +#define CONFIG_CONS_INDEX 1 /* which SMC/SCC channel for console */ + +/* + * select ethernet configuration + * + * if either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected, then + * CONFIG_ETHER_INDEX must be set to the channel number (1-4 for SCC, 1-3 + * for FCC) + * + * if CONFIG_ETHER_NONE is defined, then either the ethernet routines must be + * defined elsewhere (as for the console), or CFG_CMD_NET must be removed + * from CONFIG_COMMANDS to remove support for networking. + */ + +#undef CONFIG_ETHER_ON_SCC +#define CONFIG_ETHER_ON_FCC +#undef CONFIG_ETHER_NONE /* define if ethernet on neither */ + +#ifdef CONFIG_ETHER_ON_SCC +#define CONFIG_ETHER_INDEX 1 /* which SCC/FCC channel for ethernet */ +#endif /* CONFIG_ETHER_ON_SCC */ + +#ifdef CONFIG_ETHER_ON_FCC +#define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */ +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +/* + * Port pins used for bit-banged MII communictions (if applicable). + */ +#define MDIO_PORT 2 /* Port C */ +#define MDIO_ACTIVE (iop->pdir |= 0x00400000) +#define MDIO_TRISTATE (iop->pdir &= ~0x00400000) +#define MDIO_READ ((iop->pdat & 0x00400000) != 0) + +#define MDIO(bit) if(bit) iop->pdat |= 0x00400000; \ + else iop->pdat &= ~0x00400000 + +#define MDC(bit) if(bit) iop->pdat |= 0x00200000; \ + else iop->pdat &= ~0x00200000 + +#define MIIDELAY udelay(1) +#endif /* CONFIG_ETHER_ON_FCC */ + +#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1) + +/* + * - RX clk is CLK11 + * - TX clk is CLK12 + */ +# define CFG_CMXSCR_VALUE (CMXSCR_RS1CS_CLK11 | CMXSCR_TS1CS_CLK12) + +#elif defined(CONFIG_ETHER_ON_FCC) && (CONFIG_ETHER_INDEX == 2) + +/* + * - Rx-CLK is CLK13 + * - Tx-CLK is CLK14 + * - Select bus for bd/buffers (see 28-13) + * - Enable Full Duplex in FSMR + */ +# define CFG_CMXFCR_MASK (CMXFCR_FC2|CMXFCR_RF2CS_MSK|CMXFCR_TF2CS_MSK) +# define CFG_CMXFCR_VALUE (CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14) +# define CFG_CPMFCR_RAMTYPE 0 +# define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB) + +#endif /* CONFIG_ETHER_ON_FCC, CONFIG_ETHER_INDEX */ + +/* + * select SPI support configuration + */ +#undef CONFIG_SPI /* enable SPI driver */ + +/* + * select i2c support configuration + * + * Supported configurations are {none, software, hardware} drivers. + * If the software driver is chosen, there are some additional + * configuration items that the driver uses to drive the port pins. + */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ +#ifdef CONFIG_SOFT_I2C +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ +#endif /* CONFIG_SOFT_I2C */ + + +/* Define this to reserve an entire FLASH sector (256 KB) for + * environment variables. Otherwise, the environment will be + * put in the same sector as U-Boot, and changing variables + * will erase U-Boot temporarily + */ +#define CFG_ENV_IN_OWN_SECT 1 + +/* Define to allow the user to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* What should the console's baud rate be? */ +#define CONFIG_BAUDRATE 9600 + +/* Ethernet MAC address */ +#define CONFIG_ETHADDR 00:a0:1e:a8:7b:cb + +/* + * Define this to set the last octet of the ethernet address from the + * DS0-DS7 switch and light the LEDs with the result. The DS0-DS7 + * switch and the LEDs are backwards with respect to each other. DS7 + * is on the board edge side of both the LED strip and the DS0-DS7 + * switch. + */ +#if 0 +# define CONFIG_MISC_INIT_R +#endif + +/* Set to a positive value to delay for running BOOTCOMMAND */ +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ + +#if 0 +/* Be selective on what keys can delay or stop the autoboot process + * To stop use: " " + */ +# define CONFIG_AUTOBOOT_KEYED +# define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, press \" \" to stop\n" +# define CONFIG_AUTOBOOT_STOP_STR " " +# undef CONFIG_AUTOBOOT_DELAY_STR +# define DEBUG_BOOTKEYS 0 +#endif + +/* Define a command string that is automatically executed when no character + * is read on the console interface withing "Boot Delay" after reset. + */ +#define CONFIG_BOOT_ROOT_INITRD 0 /* Use ram disk for the root file system */ +#define CONFIG_BOOT_ROOT_NFS 1 /* Use a NFS mounted root file system */ + +#if CONFIG_BOOT_ROOT_INITRD +#define CONFIG_BOOTCOMMAND \ + "version;" \ + "echo;" \ + "bootp;" \ + "setenv bootargs root=/dev/ram0 rw " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "bootm" +#endif /* CONFIG_BOOT_ROOT_INITRD */ + +#if CONFIG_BOOT_ROOT_NFS +#define CONFIG_BOOTCOMMAND \ + "version;" \ + "echo;" \ + "bootp;" \ + "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ + "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off;" \ + "bootm" +#endif /* CONFIG_BOOT_ROOT_NFS */ + +/* Add support for a few extra bootp options like: + * - File size + * - DNS + */ +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \ + CONFIG_BOOTP_BOOTFILESIZE | \ + CONFIG_BOOTP_DNS) + +/* undef this to save memory */ +#define CFG_LONGHELP + +/* Monitor Command Prompt */ +#define CFG_PROMPT "=> " + +/* What U-Boot subsytems do you want enabled? */ +#ifdef CONFIG_ETHER_ON_FCC +# define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_ELF | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_I2C | \ + CFG_CMD_SDRAM | \ + CFG_CMD_REGINFO | \ + CFG_CMD_IMMAP | \ + CFG_CMD_MII ) +#else +# define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_ELF | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_I2C | \ + CFG_CMD_SDRAM | \ + CFG_CMD_REGINFO | \ + CFG_CMD_IMMAP ) +#endif /* CONFIG_ETHER_ON_FCC */ + +/* Where do the internal registers live? */ +#define CFG_IMMR 0xF0000000 + +/***************************************************************************** + * + * You should not have to modify any of the following settings + * + *****************************************************************************/ + +#define CONFIG_MPC8260 1 /* This is an MPC8260 CPU */ +#define CONFIG_SBC8260 1 /* on an EST SBC8260 Board */ + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +/* + * Miscellaneous configurable options + */ +#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 + +/* Print Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT)+16) + +#define CFG_MAXARGS 32 /* max number of command args */ + +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_LOAD_ADDR 0x140000 /* default load address */ +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CFG_MEMTEST_START 0x2000 /* memtest works from the end of */ + /* the exception vector table */ + /* to the end of the DRAM */ + /* less monitor and malloc area */ +#define CFG_STACK_USAGE 0x10000 /* Reserve 64k for the stack usage */ +#define CFG_MEM_END_USAGE ( CFG_MONITOR_LEN \ + + CFG_MALLOC_LEN \ + + CFG_ENV_SECT_SIZE \ + + CFG_STACK_USAGE ) + +#define CFG_MEMTEST_END ( CFG_SDRAM_SIZE * 1024 * 1024 \ + - CFG_MEM_END_USAGE ) + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ + +#define CFG_FLASH_BASE CFG_FLASH0_BASE +#define CFG_FLASH_SIZE CFG_FLASH0_SIZE +#define CFG_SDRAM_BASE CFG_SDRAM0_BASE +#define CFG_SDRAM_SIZE CFG_SDRAM0_SIZE + +/*----------------------------------------------------------------------- + * Hard Reset Configuration Words + */ +#if defined(CFG_SBC_BOOT_LOW) +# define CFG_SBC_HRCW_BOOT_FLAGS (HRCW_CIP | HRCW_BMS) +#else +# define CFG_SBC_HRCW_BOOT_FLAGS (0) +#endif /* defined(CFG_SBC_BOOT_LOW) */ + +/* get the HRCW ISB field from CFG_IMMR */ +#define CFG_SBC_HRCW_IMMR ( ((CFG_IMMR & 0x10000000) >> 10) | \ + ((CFG_IMMR & 0x01000000) >> 7) | \ + ((CFG_IMMR & 0x00100000) >> 4) ) + +#define CFG_HRCW_MASTER ( HRCW_BPS11 | \ + HRCW_DPPC11 | \ + CFG_SBC_HRCW_IMMR | \ + HRCW_MMR00 | \ + HRCW_LBPC11 | \ + HRCW_APPC10 | \ + HRCW_CS10PC00 | \ + (CFG_SBC_MODCK_H & HRCW_MODCK_H1111) | \ + CFG_SBC_HRCW_BOOT_FLAGS ) + +/* no slaves */ +#define CFG_HRCW_SLAVE1 0 +#define CFG_HRCW_SLAVE2 0 +#define CFG_HRCW_SLAVE3 0 +#define CFG_HRCW_SLAVE4 0 +#define CFG_HRCW_SLAVE5 0 +#define CFG_HRCW_SLAVE6 0 +#define CFG_HRCW_SLAVE7 0 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x4000 /* End of used area in DPRAM */ +#define CFG_GBL_DATA_SIZE 128 /* bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + * Note also that the logic that sets CFG_RAMBOOT is platform dependent. + */ +#define CFG_MONITOR_BASE CFG_FLASH0_BASE + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +# define CFG_RAMBOOT +#endif + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* 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 and environment organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 16 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 8000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 1 /* Timeout for Flash Write (in ms) */ + +#ifndef CFG_RAMBOOT +# define CFG_ENV_IS_IN_FLASH 1 + +# ifdef CFG_ENV_IN_OWN_SECT +# define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) +# define CFG_ENV_SECT_SIZE 0x40000 +# else +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_MONITOR_LEN - CFG_ENV_SECT_SIZE) +# define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ +# define CFG_ENV_SECT_SIZE 0x10000 /* see README - env sect real size */ +# endif /* CFG_ENV_IN_OWN_SECT */ + +#else +# define CFG_ENV_IS_IN_NVRAM 1 +# define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) +# define CFG_ENV_SIZE 0x200 +#endif /* CFG_RAMBOOT */ + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * HIDx - Hardware Implementation-dependent Registers 2-11 + *----------------------------------------------------------------------- + * HID0 also contains cache control - initially enable both caches and + * invalidate contents, then the final state leaves only the instruction + * cache enabled. Note that Power-On and Hard reset invalidate the caches, + * but Soft reset does not. + * + * HID1 has only read-only information - nothing to set. + */ +#define CFG_HID0_INIT (HID0_ICE |\ + HID0_DCE |\ + HID0_ICFI |\ + HID0_DCI |\ + HID0_IFEM |\ + HID0_ABE) + +#define CFG_HID0_FINAL (HID0_ICE |\ + HID0_IFEM |\ + HID0_ABE |\ + HID0_EMCP) +#define CFG_HID2 0 + +/*----------------------------------------------------------------------- + * RMR - Reset Mode Register + *----------------------------------------------------------------------- + */ +#define CFG_RMR 0 + +/*----------------------------------------------------------------------- + * BCR - Bus Configuration 4-25 + *----------------------------------------------------------------------- + */ +#define CFG_BCR (BCR_ETM) + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration 4-31 + *----------------------------------------------------------------------- + */ + +#define CFG_SIUMCR (SIUMCR_DPPC11 |\ + SIUMCR_L2CPC00 |\ + SIUMCR_APPC10 |\ + SIUMCR_MMR00) + + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Watchdog & Bus Monitor Timer max, 60x Bus Monitor enable + */ +#define CFG_SYPCR (SYPCR_SWTC |\ + SYPCR_BMT |\ + SYPCR_PBME |\ + SYPCR_LBME |\ + SYPCR_SWRI |\ + SYPCR_SWP) + +/*----------------------------------------------------------------------- + * TMCNTSC - Time Counter Status and Control 4-40 + *----------------------------------------------------------------------- + * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk, + * and enable Time Counter + */ +#define CFG_TMCNTSC (TMCNTSC_SEC |\ + TMCNTSC_ALR |\ + TMCNTSC_TCF |\ + TMCNTSC_TCE) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 4-42 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable + * Periodic timer + */ +#define CFG_PISCR (PISCR_PS |\ + PISCR_PTF |\ + PISCR_PTE) + +/*----------------------------------------------------------------------- + * SCCR - System Clock Control 9-8 + *----------------------------------------------------------------------- + */ +#define CFG_SCCR 0 + +/*----------------------------------------------------------------------- + * RCCR - RISC Controller Configuration 13-7 + *----------------------------------------------------------------------- + */ +#define CFG_RCCR 0 + +/* + * Initialize Memory Controller: + * + * Bank Bus Machine PortSz Device + * ---- --- ------- ------ ------ + * 0 60x GPCM 32 bit FLASH (SIMM - 4MB) * + * 1 60x GPCM 32 bit FLASH (SIMM - Unused) + * 2 60x SDRAM 64 bit SDRAM (DIMM - 16MB or 64MB) + * 3 60x SDRAM 64 bit SDRAM (DIMM - Unused) + * 4 Local SDRAM 32 bit SDRAM (on board - 4MB) + * 5 60x GPCM 8 bit EEPROM (8KB) + * 6 60x GPCM 8 bit FLASH (on board - 2MB) * + * 7 60x GPCM 8 bit LEDs, switches + * + * (*) This configuration requires the SBC8260 be configured + * so that *CS0 goes to the FLASH SIMM, and *CS6 goes to + * the on board FLASH. In other words, JP24 should have + * pins 1 and 2 jumpered and pins 3 and 4 jumpered. + * + */ + +/*----------------------------------------------------------------------- + * BR0,BR1 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR0,OR1 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 0,1 - FLASH SIMM + * + * This expects the FLASH SIMM to be connected to *CS0 + * It consists of 4 AM29F080B parts. + * + * Note: For the 4 MB SIMM, *CS1 is unused. + */ + +/* BR0 is configured as follows: + * + * - Base address of 0x40000000 + * - 32 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR0_PRELIM ((CFG_FLASH0_BASE & BRx_BA_MSK) |\ + BRx_PS_32 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR0 is configured as follows: + * + * - 4 MB + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 5 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +#define CFG_OR0_PRELIM (MEG_TO_AM(CFG_FLASH0_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) + +/*----------------------------------------------------------------------- + * BR2,BR3 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR2,OR3 - Option Register + * Ref: Section 10.3.2 on page 10-16 + *----------------------------------------------------------------------- + */ + +/* Bank 2,3 - SDRAM DIMM + * + * 16MB DIMM: P/N + * 64MB DIMM: P/N 1W-8864X8-4-P1-EST + * + * Note: *CS3 is unused for this DIMM + */ + +/* With a 16 MB or 64 MB DIMM, the BR2 is configured as follows: + * + * - Base address of 0x00000000 + * - 64 bit port size (60x bus only) + * - Data errors checking is disabled + * - Read and write access + * - SDRAM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +#define CFG_BR2_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +#define CFG_BR3_PRELIM ((CFG_SDRAM0_BASE & BRx_BA_MSK) |\ + BRx_PS_64 |\ + BRx_MS_SDRAM_P |\ + BRx_V) + +/* With a 16 MB DIMM, the OR2 is configured as follows: + * + * - 16 MB + * - 2 internal banks per device + * - Row start address bit is A9 with PSDMR[PBI] = 0 + * - 11 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ +#if (CFG_SDRAM0_SIZE == 16) +#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\ + ORxS_BPD_2 |\ + ORxS_ROWST_PBI0_A9 |\ + ORxS_NUMR_11) +#endif + +/* With a 64 MB DIMM, the OR2 is configured as follows: + * + * - 64 MB + * - 4 internal banks per device + * - Row start address bit is A8 with PSDMR[PBI] = 0 + * - 12 row address lines + * - Back-to-back page mode + * - Internal bank interleaving within save device enabled + */ +#if (CFG_SDRAM0_SIZE == 64) +#define CFG_OR2_PRELIM (MEG_TO_AM(CFG_SDRAM0_SIZE) |\ + ORxS_BPD_4 |\ + ORxS_ROWST_PBI0_A8 |\ + ORxS_NUMR_12) +#endif + +/*----------------------------------------------------------------------- + * PSDMR - 60x Bus SDRAM Mode Register + * Ref: Section 10.3.3 on page 10-21 + *----------------------------------------------------------------------- + */ + +/* Address that the DIMM SPD memory lives at. + */ +#define SDRAM_SPD_ADDR 0x54 + +#if (CFG_SDRAM0_SIZE == 16) +/* With a 16 MB DIMM, the PSDMR is configured as follows: + * + * - Bank Based Interleaving, + * - Refresh Enable, + * - Address Multiplexing where A5 is output on A14 pin + * (A6 on A15, and so on), + * - use address pins A16-A18 as bank select, + * - A9 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 3 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - CAS Latency is 2. + */ +#define CFG_PSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A16_A18 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) +#endif + +#if (CFG_SDRAM0_SIZE == 64) +/* With a 64 MB DIMM, the PSDMR is configured as follows: + * + * - Bank Based Interleaving, + * - Refresh Enable, + * - Address Multiplexing where A5 is output on A14 pin + * (A6 on A15, and so on), + * - use address pins A14-A16 as bank select, + * - A9 is output on SDA10 during an ACTIVATE command, + * - earliest timing for ACTIVATE command after REFRESH command is 7 clocks, + * - earliest timing for ACTIVATE or REFRESH command after PRECHARGE command + * is 3 clocks, + * - earliest timing for READ/WRITE command after ACTIVATE command is + * 2 clocks, + * - earliest timing for PRECHARGE after last data was read is 1 clock, + * - earliest timing for PRECHARGE after last data was written is 1 clock, + * - CAS Latency is 2. + */ +#define CFG_PSDMR (PSDMR_RFEN |\ + PSDMR_SDAM_A14_IS_A5 |\ + PSDMR_BSMA_A14_A16 |\ + PSDMR_SDA10_PBI0_A9 |\ + PSDMR_RFRC_7_CLK |\ + PSDMR_PRETOACT_3W |\ + PSDMR_ACTTORW_2W |\ + PSDMR_LDOTOPRE_1C |\ + PSDMR_WRC_1C |\ + PSDMR_CL_2) +#endif + +/* + * Shoot for approximately 1MHz on the prescaler. + */ +#if (CONFIG_8260_CLKIN == (66 * 1000 * 1000)) +#define CFG_MPTPR MPTPR_PTP_DIV64 +#elif (CONFIG_8260_CLKIN == (33 * 1000 * 1000)) +#define CFG_MPTPR MPTPR_PTP_DIV32 +#else +#warning "Unconfigured bus clock freq: check CFG_MPTPR and CFG_PSRT are OK" +#define CFG_MPTPR MPTPR_PTP_DIV32 +#endif +#define CFG_PSRT 14 + + +/* Bank 4 - On board SDRAM + * + * This is not implemented yet. + */ + +/*----------------------------------------------------------------------- + * BR6 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR6 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 6 - On board FLASH + * + * This expects the on board FLASH SIMM to be connected to *CS6 + * It consists of 1 AM29F016A part. + */ +#if (defined(CFG_FLASH1_BASE) && defined(CFG_FLASH1_SIZE)) + +/* BR6 is configured as follows: + * + * - Base address of 0x60000000 + * - 8 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +# define CFG_BR6_PRELIM ((CFG_FLASH1_BASE & BRx_BA_MSK) |\ + BRx_PS_8 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR6 is configured as follows: + * + * - 2 MB + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 5 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +# define CFG_OR6_PRELIM (MEG_TO_AM(CFG_FLASH1_SIZE) |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_5_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) +#endif /* (defined(CFG_FLASH1_BASE) && defined(CFG_FLASH1_SIZE)) */ + +/*----------------------------------------------------------------------- + * BR7 - Base Register + * Ref: Section 10.3.1 on page 10-14 + * OR7 - Option Register + * Ref: Section 10.3.2 on page 10-18 + *----------------------------------------------------------------------- + */ + +/* Bank 7 - LEDs and switches + * + * LEDs are at 0x00001 (write only) + * switches are at 0x00001 (read only) + */ +#ifdef CFG_LED_BASE + +/* BR7 is configured as follows: + * + * - Base address of 0xA0000000 + * - 8 bit port size + * - Data errors checking is disabled + * - Read and write access + * - GPCM 60x bus + * - Access are handled by the memory controller according to MSEL + * - Not used for atomic operations + * - No data pipelining is done + * - Valid + */ +# define CFG_BR7_PRELIM ((CFG_LED_BASE & BRx_BA_MSK) |\ + BRx_PS_8 |\ + BRx_MS_GPCM_P |\ + BRx_V) + +/* OR7 is configured as follows: + * + * - 1 byte + * - *BCTL0 is asserted upon access to the current memory bank + * - *CW / *WE are negated a quarter of a clock earlier + * - *CS is output at the same time as the address lines + * - Uses a clock cycle length of 15 + * - *PSDVAL is generated internally by the memory controller + * unless *GTA is asserted earlier externally. + * - Relaxed timing is generated by the GPCM for accesses + * initiated to this memory region. + * - One idle clock is inserted between a read access from the + * current bank and the next access. + */ +# define CFG_OR7_PRELIM (ORxG_AM_MSK |\ + ORxG_CSNT |\ + ORxG_ACS_DIV1 |\ + ORxG_SCY_15_CLK |\ + ORxG_TRLX |\ + ORxG_EHTR) +#endif /* CFG_LED_BASE */ + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ diff --git a/include/galileo/pci.h b/include/galileo/pci.h new file mode 100644 index 0000000..f45dd36 --- /dev/null +++ b/include/galileo/pci.h @@ -0,0 +1,113 @@ +/* PCI.h - PCI functions header file */ + +/* Copyright - Galileo technology. */ + +#ifndef __INCpcih +#define __INCpcih + +/* includes */ + +#include "core.h" +#include "memory.h" + +/* According to PCI REV 2.1 MAX agents allowed on the bus are -21- */ +#define PCI_MAX_DEVICES 22 + + +/* Macros */ +#define SELF 32 + +/* Defines for the access regions. */ +#define PREFETCH_ENABLE BIT12 +#define PREFETCH_DISABLE NO_BIT +#define DELAYED_READ_ENABLE BIT13 +/* #define CACHING_ENABLE BIT14 */ +/* aggressive prefetch: PCI slave prefetch two burst in advance*/ +#define AGGRESSIVE_PREFETCH BIT16 +/* read line aggresive prefetch: PCI slave prefetch two burst in advance*/ +#define READ_LINE_AGGRESSIVE_PREFETCH BIT17 +/* read multiple aggresive prefetch: PCI slave prefetch two burst in advance*/ +#define READ_MULTI_AGGRESSIVE_PREFETCH BIT18 +#define MAX_BURST_4 NO_BIT +#define MAX_BURST_8 BIT20 /* Bits[21:20] = 01 */ +#define MAX_BURST_16 BIT21 /* Bits[21:20] = 10 */ +#define PCI_BYTE_SWAP NO_BIT /* Bits[25:24] = 00 */ +#define PCI_NO_SWAP BIT24 /* Bits[25:24] = 01 */ +#define PCI_BYTE_AND_WORD_SWAP BIT25 /* Bits[25:24] = 10 */ +#define PCI_WORD_SWAP (BIT24 | BIT25) /* Bits[25:24] = 11 */ +#define PCI_ACCESS_PROTECT BIT28 +#define PCI_WRITE_PROTECT BIT29 + +/* typedefs */ + +typedef enum __pciAccessRegions{REGION0,REGION1,REGION2,REGION3,REGION4,REGION5, + REGION6,REGION7} PCI_ACCESS_REGIONS; + +typedef enum __pciAgentPrio{LOW_AGENT_PRIO,HI_AGENT_PRIO} PCI_AGENT_PRIO; +typedef enum __pciAgentPark{PARK_ON_AGENT,DONT_PARK_ON_AGENT} PCI_AGENT_PARK; + +typedef enum __pciSnoopType{PCI_NO_SNOOP,PCI_SNOOP_WT,PCI_SNOOP_WB} + PCI_SNOOP_TYPE; +typedef enum __pciSnoopRegion{PCI_SNOOP_REGION0,PCI_SNOOP_REGION1, + PCI_SNOOP_REGION2,PCI_SNOOP_REGION3} + PCI_SNOOP_REGION; + +typedef enum __memPciHost{PCI_HOST0,PCI_HOST1} PCI_HOST; +typedef enum __memPciRegion{PCI_REGION0,PCI_REGION1, + PCI_REGION2,PCI_REGION3, + PCI_IO} + PCI_REGION; + +/* read/write configuration registers on local PCI bus. */ +void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset, + unsigned int pciDevNum, unsigned int data); +unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset, + unsigned int pciDevNum); + +/* read/write configuration registers on another PCI bus. */ +void pciOverBridgeWriteConfigReg(PCI_HOST host, + unsigned int regOffset, + unsigned int pciDevNum, + unsigned int busNum,unsigned int data); +unsigned int pciOverBridgeReadConfigReg(PCI_HOST host, + unsigned int regOffset, + unsigned int pciDevNum, + unsigned int busNum); + +/* Master`s memory space */ +bool pciMapSpace(PCI_HOST host, PCI_REGION region, + unsigned int remapBase, + unsigned int deviceBase, + unsigned int deviceLength); +unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region); +unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region); + +/* Slave`s memory space */ +void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank, + unsigned int pci0Dram0Base, unsigned int pci0Dram0Size); + +/* PCI region options */ + +bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region, + unsigned int features, unsigned int baseAddress, + unsigned int regionLength); + +void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region); + +/* PCI arbiter */ + +bool pciArbiterEnable(PCI_HOST host); +bool pciArbiterDisable(PCI_HOST host); +bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent, + PCI_AGENT_PARK externalAgent0, + PCI_AGENT_PARK externalAgent1, + PCI_AGENT_PARK externalAgent2, + PCI_AGENT_PARK externalAgent3, + PCI_AGENT_PARK externalAgent4, + PCI_AGENT_PARK externalAgent5); +bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region, + PCI_SNOOP_TYPE snoopType, + unsigned int baseAddress, + unsigned int regionLength); + +#endif /* __INCpcih */ diff --git a/include/jffs2/jffs2.h b/include/jffs2/jffs2.h new file mode 100644 index 0000000..9098690 --- /dev/null +++ b/include/jffs2/jffs2.h @@ -0,0 +1,208 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright (C) 2001 Red Hat, Inc. + * + * Created by David Woodhouse <dwmw2@cambridge.redhat.com> + * + * The original JFFS, from which the design for JFFS2 was derived, + * was designed and implemented by Axis Communications AB. + * + * The contents of this file are subject to the Red Hat eCos Public + * License Version 1.1 (the "Licence"); you may not use this file + * except in compliance with the Licence. You may obtain a copy of + * the Licence at http://www.redhat.com/ + * + * Software distributed under the Licence is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the Licence for the specific language governing rights and + * limitations under the Licence. + * + * The Original Code is JFFS2 - Journalling Flash File System, version 2 + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the RHEPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + * + * $Id: jffs2.h,v 1.2 2002/01/17 00:53:20 nyet Exp $ + * + */ + +#ifndef __LINUX_JFFS2_H__ +#define __LINUX_JFFS2_H__ + +#include <asm/types.h> +#include <jffs2/load_kernel.h> + +#define JFFS2_SUPER_MAGIC 0x72b6 + +/* Values we may expect to find in the 'magic' field */ +#define JFFS2_OLD_MAGIC_BITMASK 0x1984 +#define JFFS2_MAGIC_BITMASK 0x1985 +#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */ +#define JFFS2_EMPTY_BITMASK 0xffff +#define JFFS2_DIRTY_BITMASK 0x0000 + +/* We only allow a single char for length, and 0xFF is empty flash so + we don't want it confused with a real length. Hence max 254. +*/ +#define JFFS2_MAX_NAME_LEN 254 + +/* How small can we sensibly write nodes? */ +#define JFFS2_MIN_DATA_LEN 128 + +#define JFFS2_COMPR_NONE 0x00 +#define JFFS2_COMPR_ZERO 0x01 +#define JFFS2_COMPR_RTIME 0x02 +#define JFFS2_COMPR_RUBINMIPS 0x03 +#define JFFS2_COMPR_COPY 0x04 +#define JFFS2_COMPR_DYNRUBIN 0x05 +#define JFFS2_COMPR_ZLIB 0x06 +#define JFFS2_NUM_COMPR 7 + +/* Compatibility flags. */ +#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ +#define JFFS2_NODE_ACCURATE 0x2000 +/* INCOMPAT: Fail to mount the filesystem */ +#define JFFS2_FEATURE_INCOMPAT 0xc000 +/* ROCOMPAT: Mount read-only */ +#define JFFS2_FEATURE_ROCOMPAT 0x8000 +/* RWCOMPAT_COPY: Mount read/write, and copy the node when it's GC'd */ +#define JFFS2_FEATURE_RWCOMPAT_COPY 0x4000 +/* RWCOMPAT_DELETE: Mount read/write, and delete the node when it's GC'd */ +#define JFFS2_FEATURE_RWCOMPAT_DELETE 0x0000 + +#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1) +#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) +#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) + +/* Maybe later... */ +/*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */ +/*#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) */ + +/* Same as the non_ECC versions, but with extra space for real + * ECC instead of just the checksum. For use on NAND flash + */ +/*#define JFFS2_NODETYPE_DIRENT_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 5) */ +/*#define JFFS2_NODETYPE_INODE_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 6) */ + +#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at + mount time, don't wait for it to + happen later */ +#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific + compression type */ + + +struct jffs2_unknown_node +{ + /* All start like this */ + __u16 magic; + __u16 nodetype; + __u32 totlen; /* So we can skip over nodes we don't grok */ + __u32 hdr_crc; +} __attribute__((packed)); + +struct jffs2_raw_dirent +{ + __u16 magic; + __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */ + __u32 totlen; + __u32 hdr_crc; + __u32 pino; + __u32 version; + __u32 ino; /* == zero for unlink */ + __u32 mctime; + __u8 nsize; + __u8 type; + __u8 unused[2]; + __u32 node_crc; + __u32 name_crc; + __u8 name[0]; +} __attribute__((packed)); + +/* The JFFS2 raw inode structure: Used for storage on physical media. */ +/* The uid, gid, atime, mtime and ctime members could be longer, but + are left like this for space efficiency. If and when people decide + they really need them extended, it's simple enough to add support for + a new type of raw node. +*/ +struct jffs2_raw_inode +{ + __u16 magic; /* A constant magic number. */ + __u16 nodetype; /* == JFFS_NODETYPE_INODE */ + __u32 totlen; /* Total length of this node (inc data, etc.) */ + __u32 hdr_crc; + __u32 ino; /* Inode number. */ + __u32 version; /* Version number. */ + __u32 mode; /* The file's type or mode. */ + __u16 uid; /* The file's owner. */ + __u16 gid; /* The file's group. */ + __u32 isize; /* Total resultant size of this inode (used for truncations) */ + __u32 atime; /* Last access time. */ + __u32 mtime; /* Last modification time. */ + __u32 ctime; /* Change time. */ + __u32 offset; /* Where to begin to write. */ + __u32 csize; /* (Compressed) data size */ + __u32 dsize; /* Size of the node's data. (after decompression) */ + __u8 compr; /* Compression algorithm used */ + __u8 usercompr; /* Compression algorithm requested by the user */ + __u16 flags; /* See JFFS2_INO_FLAG_* */ + __u32 data_crc; /* CRC for the (compressed) data. */ + __u32 node_crc; /* CRC for the raw inode (excluding data) */ +/* __u8 data[dsize]; */ +} __attribute__((packed)); + +union jffs2_node_union { + struct jffs2_raw_inode i; + struct jffs2_raw_dirent d; + struct jffs2_unknown_node u; +} __attribute__((packed)); + +enum + { + DT_UNKNOWN = 0, +# define DT_UNKNOWN DT_UNKNOWN + DT_FIFO = 1, +# define DT_FIFO DT_FIFO + DT_CHR = 2, +# define DT_CHR DT_CHR + DT_DIR = 4, +# define DT_DIR DT_DIR + DT_BLK = 6, +# define DT_BLK DT_BLK + DT_REG = 8, +# define DT_REG DT_REG + DT_LNK = 10, +# define DT_LNK DT_LNK + DT_SOCK = 12, +# define DT_SOCK DT_SOCK + DT_WHT = 14 +# define DT_WHT DT_WHT + }; + + +u32 jffs2_1pass_ls(struct part_info *part,const char *fname); +u32 jffs2_1pass_load(char *dest, struct part_info *part,const char *fname); +u32 jffs2_1pass_info(struct part_info *part); + +void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, u32 + srclen, u32 destlen); +void rubin_do_decompress(unsigned char *bits, unsigned char *in, unsigned char + *page_out, __u32 destlen); +void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, + unsigned long sourcelen, unsigned long dstlen); +long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, + __u32 srclen, __u32 destlen); + + + + + +#endif /* __LINUX_JFFS2_H__ */ diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h new file mode 100644 index 0000000..d8b4240 --- /dev/null +++ b/include/jffs2/load_kernel.h @@ -0,0 +1,76 @@ +#ifndef load_kernel_h +#define load_kernel_h +/*------------------------------------------------------------------------- + * Filename: load_kernel.h + * Version: $Id: load_kernel.h,v 1.3 2002/01/25 01:34:11 nyet Exp $ + * Copyright: Copyright (C) 2001, Russ Dill + * Author: Russ Dill <Russ.Dill@asu.edu> + * Description: header for load kernel modules + *-----------------------------------------------------------------------*/ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* this struct is very similar to mtd_info */ +struct part_info { + u32 size; /* Total size of the Partition */ + + /* "Major" erase size for the device. Naïve users may take this + * to be the only erase size available, or may use the more detailed + * information below if they desire + */ + u32 erasesize; + + /* Where in memory does this partition start? */ + char *offset; + + /* used by jffs2 set to NULL */ + void *jffs2_priv; + + /* private filed used by user */ + void *usr_priv; +}; + +struct part_info* +jffs2_part_info(int part_num); + +struct kernel_loader { + + /* Return true if there is a kernel contained at src */ + int (* check_magic)(struct part_info *part); + + /* load the kernel from the partition part to dst, return the number + * of bytes copied if successful, zero if not */ + u32 (* load_kernel)(u32 *dst, struct part_info *part, const char *kernel_filename); + + /* A brief description of the module (ie, "cramfs") */ + char *name; +}; + +#define ldr_strlen strlen +#define ldr_strncmp strncmp +#define ldr_memcpy memcpy +#define putstr(x) printf("%s", x) +#define mmalloc malloc +#define UDEBUG printf + +#define putnstr(str, size) printf("%*.*s", size, size, str) +#define ldr_output_string(x) puts(x) +#define putLabeledWord(x, y) printf("%s %08x\n", x, (unsigned int)y) +#define led_blink(x, y, z, a) + +#endif /* load_kernel_h */ diff --git a/include/lcd.h b/include/lcd.h new file mode 100644 index 0000000..d063c9c --- /dev/null +++ b/include/lcd.h @@ -0,0 +1,39 @@ +/* + * MPC823 LCD Controller + * + * Modeled after video interface by Paolo Scaffardi + * + * + * (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 + */ + +#ifndef _LCD_H_ +#define _LCD_H_ + +/* Video functions */ + +int lcd_init (void *lcdbase); +void lcd_putc (const char c); +void lcd_puts (const char *s); +void lcd_printf (const char *fmt, ...); + +#endif diff --git a/include/pci_ids.h b/include/pci_ids.h new file mode 100644 index 0000000..87de6a9 --- /dev/null +++ b/include/pci_ids.h @@ -0,0 +1,1524 @@ +/* + * PCI Class, Vendor and Device IDs + * + * Please keep sorted. + */ + +/* Device classes and subclasses */ + +#define PCI_CLASS_NOT_DEFINED 0x0000 +#define PCI_CLASS_NOT_DEFINED_VGA 0x0001 + +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_CLASS_STORAGE_SCSI 0x0100 +#define PCI_CLASS_STORAGE_IDE 0x0101 +#define PCI_CLASS_STORAGE_FLOPPY 0x0102 +#define PCI_CLASS_STORAGE_IPI 0x0103 +#define PCI_CLASS_STORAGE_RAID 0x0104 +#define PCI_CLASS_STORAGE_OTHER 0x0180 + +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x0200 +#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 +#define PCI_CLASS_NETWORK_FDDI 0x0202 +#define PCI_CLASS_NETWORK_ATM 0x0203 +#define PCI_CLASS_NETWORK_OTHER 0x0280 + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_VGA 0x0300 +#define PCI_CLASS_DISPLAY_XGA 0x0301 +#define PCI_CLASS_DISPLAY_3D 0x0302 +#define PCI_CLASS_DISPLAY_OTHER 0x0380 + +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 +#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 +#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402 +#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 + +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_CLASS_MEMORY_RAM 0x0500 +#define PCI_CLASS_MEMORY_FLASH 0x0501 +#define PCI_CLASS_MEMORY_OTHER 0x0580 + +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x0600 +#define PCI_CLASS_BRIDGE_ISA 0x0601 +#define PCI_CLASS_BRIDGE_EISA 0x0602 +#define PCI_CLASS_BRIDGE_MC 0x0603 +#define PCI_CLASS_BRIDGE_PCI 0x0604 +#define PCI_CLASS_BRIDGE_PCMCIA 0x0605 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 +#define PCI_CLASS_BRIDGE_RACEWAY 0x0608 +#define PCI_CLASS_BRIDGE_OTHER 0x0680 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 +#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702 +#define PCI_CLASS_COMMUNICATION_MODEM 0x0703 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_DMA 0x0801 +#define PCI_CLASS_SYSTEM_TIMER 0x0802 +#define PCI_CLASS_SYSTEM_RTC 0x0803 +#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804 +#define PCI_CLASS_SYSTEM_OTHER 0x0880 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900 +#define PCI_CLASS_INPUT_PEN 0x0901 +#define PCI_CLASS_INPUT_MOUSE 0x0902 +#define PCI_CLASS_INPUT_SCANNER 0x0903 +#define PCI_CLASS_INPUT_GAMEPORT 0x0904 +#define PCI_CLASS_INPUT_OTHER 0x0980 + +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_CLASS_DOCKING_GENERIC 0x0a00 +#define PCI_CLASS_DOCKING_OTHER 0x0a80 + +#define PCI_BASE_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_PROCESSOR_386 0x0b00 +#define PCI_CLASS_PROCESSOR_486 0x0b01 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20 +#define PCI_CLASS_PROCESSOR_MIPS 0x0b30 +#define PCI_CLASS_PROCESSOR_CO 0x0b40 + +#define PCI_BASE_CLASS_SERIAL 0x0c +#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00 +#define PCI_CLASS_SERIAL_ACCESS 0x0c01 +#define PCI_CLASS_SERIAL_SSA 0x0c02 +#define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_FIBER 0x0c04 +#define PCI_CLASS_SERIAL_SMBUS 0x0c05 + +#define PCI_BASE_CLASS_INTELLIGENT 0x0e +#define PCI_CLASS_INTELLIGENT_I2O 0x0e00 + +#define PCI_BASE_CLASS_SATELLITE 0x0f +#define PCI_CLASS_SATELLITE_TV 0x0f00 +#define PCI_CLASS_SATELLITE_AUDIO 0x0f01 +#define PCI_CLASS_SATELLITE_VOICE 0x0f03 +#define PCI_CLASS_SATELLITE_DATA 0x0f04 + +#define PCI_BASE_CLASS_CRYPT 0x10 +#define PCI_CLASS_CRYPT_NETWORK 0x1000 +#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001 +#define PCI_CLASS_CRYPT_OTHER 0x1080 + +#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11 +#define PCI_CLASS_SP_DPIO 0x1100 +#define PCI_CLASS_SP_OTHER 0x1180 + +#define PCI_CLASS_OTHERS 0xff + +/* Vendors and devices. Sort key: vendor first, device next. */ + +#define PCI_VENDOR_ID_DYNALINK 0x0675 +#define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702 + +#define PCI_VENDOR_ID_BERKOM 0x0871 +#define PCI_DEVICE_ID_BERKOM_A1T 0xffa1 +#define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2 +#define PCI_DEVICE_ID_BERKOM_A4T 0xffa4 +#define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO 0xffa8 + +#define PCI_VENDOR_ID_COMPAQ 0x0e11 +#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508 +#define PCI_DEVICE_ID_COMPAQ_1280 0x3033 +#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000 +#define PCI_DEVICE_ID_COMPAQ_6010 0x6010 +#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 +#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 +#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35 +#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40 +#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43 +#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011 +#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060 +#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178 +#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150 + +#define PCI_VENDOR_ID_NCR 0x1000 +#define PCI_DEVICE_ID_NCR_53C810 0x0001 +#define PCI_DEVICE_ID_NCR_53C820 0x0002 +#define PCI_DEVICE_ID_NCR_53C825 0x0003 +#define PCI_DEVICE_ID_NCR_53C815 0x0004 +#define PCI_DEVICE_ID_NCR_53C860 0x0006 +#define PCI_DEVICE_ID_NCR_53C896 0x000b +#define PCI_DEVICE_ID_NCR_53C895 0x000c +#define PCI_DEVICE_ID_NCR_53C885 0x000d +#define PCI_DEVICE_ID_NCR_53C875 0x000f +#define PCI_DEVICE_ID_NCR_53C1510 0x0010 +#define PCI_DEVICE_ID_NCR_53C875J 0x008f +#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701 + +#define PCI_VENDOR_ID_ATI 0x1002 +#define PCI_DEVICE_ID_ATI_68800 0x4158 +#define PCI_DEVICE_ID_ATI_215CT222 0x4354 +#define PCI_DEVICE_ID_ATI_210888CX 0x4358 +#define PCI_DEVICE_ID_ATI_215GB 0x4742 +#define PCI_DEVICE_ID_ATI_215GD 0x4744 +#define PCI_DEVICE_ID_ATI_215GI 0x4749 +#define PCI_DEVICE_ID_ATI_215GP 0x4750 +#define PCI_DEVICE_ID_ATI_215GQ 0x4751 +#define PCI_DEVICE_ID_ATI_215GT 0x4754 +#define PCI_DEVICE_ID_ATI_215GTB 0x4755 +#define PCI_DEVICE_ID_ATI_210888GX 0x4758 +#define PCI_DEVICE_ID_ATI_215LG 0x4c47 +#define PCI_DEVICE_ID_ATI_264LT 0x4c54 +#define PCI_DEVICE_ID_ATI_264VT 0x5654 +#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245 +#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246 +#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b +#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c +#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046 +#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052 +#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45 +#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46 + +#define PCI_VENDOR_ID_VLSI 0x1004 +#define PCI_DEVICE_ID_VLSI_82C592 0x0005 +#define PCI_DEVICE_ID_VLSI_82C593 0x0006 +#define PCI_DEVICE_ID_VLSI_82C594 0x0007 +#define PCI_DEVICE_ID_VLSI_82C597 0x0009 +#define PCI_DEVICE_ID_VLSI_82C541 0x000c +#define PCI_DEVICE_ID_VLSI_82C543 0x000d +#define PCI_DEVICE_ID_VLSI_82C532 0x0101 +#define PCI_DEVICE_ID_VLSI_82C534 0x0102 +#define PCI_DEVICE_ID_VLSI_82C535 0x0104 +#define PCI_DEVICE_ID_VLSI_82C147 0x0105 +#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 + +#define PCI_VENDOR_ID_ADL 0x1005 +#define PCI_DEVICE_ID_ADL_2301 0x2301 + +#define PCI_VENDOR_ID_NS 0x100b +#define PCI_DEVICE_ID_NS_83815 0x0020 +#define PCI_DEVICE_ID_NS_8382x 0x0022 +#define PCI_DEVICE_ID_NS_87415 0x0002 +#define PCI_DEVICE_ID_NS_87560_LIO 0x000e +#define PCI_DEVICE_ID_NS_87560_USB 0x0012 +#define PCI_DEVICE_ID_NS_87410 0xd001 + +#define PCI_VENDOR_ID_TSENG 0x100c +#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 +#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 +#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 +#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 +#define PCI_DEVICE_ID_TSENG_ET6000 0x3208 + +#define PCI_VENDOR_ID_WEITEK 0x100e +#define PCI_DEVICE_ID_WEITEK_P9000 0x9001 +#define PCI_DEVICE_ID_WEITEK_P9100 0x9100 + +#define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_DEVICE_ID_DEC_BRD 0x0001 +#define PCI_DEVICE_ID_DEC_TULIP 0x0002 +#define PCI_DEVICE_ID_DEC_TGA 0x0004 +#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 +#define PCI_DEVICE_ID_DEC_TGA2 0x000D +#define PCI_DEVICE_ID_DEC_FDDI 0x000F +#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 +#define PCI_DEVICE_ID_DEC_21142 0x0019 +#define PCI_DEVICE_ID_DEC_21052 0x0021 +#define PCI_DEVICE_ID_DEC_21150 0x0022 +#define PCI_DEVICE_ID_DEC_21152 0x0024 +#define PCI_DEVICE_ID_DEC_21153 0x0025 +#define PCI_DEVICE_ID_DEC_21154 0x0026 +#define PCI_DEVICE_ID_DEC_21285 0x1065 +#define PCI_DEVICE_ID_COMPAQ_42XX 0x0046 + +#define PCI_VENDOR_ID_CIRRUS 0x1013 +#define PCI_DEVICE_ID_CIRRUS_7548 0x0038 +#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 +#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4 +#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8 +#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac +#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8 +#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc +#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0 +#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4 +#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6 +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 +#define PCI_DEVICE_ID_CIRRUS_6832 0x1110 +#define PCI_DEVICE_ID_CIRRUS_7542 0x1200 +#define PCI_DEVICE_ID_CIRRUS_7543 0x1202 +#define PCI_DEVICE_ID_CIRRUS_7541 0x1204 + +#define PCI_VENDOR_ID_IBM 0x1014 +#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a +#define PCI_DEVICE_ID_IBM_TR 0x0018 +#define PCI_DEVICE_ID_IBM_82G2675 0x001d +#define PCI_DEVICE_ID_IBM_MCA 0x0020 +#define PCI_DEVICE_ID_IBM_82351 0x0022 +#define PCI_DEVICE_ID_IBM_PYTHON 0x002d +#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e +#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e +#define PCI_DEVICE_ID_IBM_MPIC 0x0046 +#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d +#define PCI_DEVICE_ID_IBM_CPC700 0x00f9 +#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc +#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105 +#define PCI_DEVICE_ID_IBM_405GP 0x0156 +#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff + +#define PCI_VENDOR_ID_COMPEX2 0x101a /* pci.ids says "AT&T GIS (NCR)" */ +#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 + +#define PCI_VENDOR_ID_WD 0x101c +#define PCI_DEVICE_ID_WD_7197 0x3296 + +#define PCI_VENDOR_ID_AMI 0x101e +#define PCI_DEVICE_ID_AMI_MEGARAID3 0x1960 +#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010 +#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060 + +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 +#define PCI_DEVICE_ID_AMD_SCSI 0x2020 +#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006 +#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400 +#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401 +#define PCI_DEVICE_ID_AMD_COBRA_7403 0x7403 +#define PCI_DEVICE_ID_AMD_COBRA_7404 0x7404 +#define PCI_DEVICE_ID_AMD_VIPER_7408 0x7408 +#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409 +#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B +#define PCI_DEVICE_ID_AMD_VIPER_740C 0x740C + +#define PCI_VENDOR_ID_TRIDENT 0x1023 +#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 +#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 +#define PCI_DEVICE_ID_TRIDENT_9320 0x9320 +#define PCI_DEVICE_ID_TRIDENT_9388 0x9388 +#define PCI_DEVICE_ID_TRIDENT_9397 0x9397 +#define PCI_DEVICE_ID_TRIDENT_939A 0x939A +#define PCI_DEVICE_ID_TRIDENT_9520 0x9520 +#define PCI_DEVICE_ID_TRIDENT_9525 0x9525 +#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 +#define PCI_DEVICE_ID_TRIDENT_9440 0x9440 +#define PCI_DEVICE_ID_TRIDENT_9660 0x9660 +#define PCI_DEVICE_ID_TRIDENT_9750 0x9750 +#define PCI_DEVICE_ID_TRIDENT_9850 0x9850 +#define PCI_DEVICE_ID_TRIDENT_9880 0x9880 +#define PCI_DEVICE_ID_TRIDENT_8400 0x8400 +#define PCI_DEVICE_ID_TRIDENT_8420 0x8420 +#define PCI_DEVICE_ID_TRIDENT_8500 0x8500 + +#define PCI_VENDOR_ID_AI 0x1025 +#define PCI_DEVICE_ID_AI_M1435 0x1435 + +#define PCI_VENDOR_ID_MATROX 0x102B +#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 +#define PCI_DEVICE_ID_MATROX_MIL 0x0519 +#define PCI_DEVICE_ID_MATROX_MYS 0x051A +#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b +#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f +#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 +#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000 +#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001 +#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 +#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 +#define PCI_DEVICE_ID_MATROX_G400 0x0525 +#define PCI_DEVICE_ID_MATROX_VIA 0x4536 + +#define PCI_VENDOR_ID_CT 0x102c +#define PCI_DEVICE_ID_CT_65545 0x00d8 +#define PCI_DEVICE_ID_CT_65548 0x00dc +#define PCI_DEVICE_ID_CT_65550 0x00e0 +#define PCI_DEVICE_ID_CT_65554 0x00e4 +#define PCI_DEVICE_ID_CT_65555 0x00e5 +#define PCI_DEVICE_ID_CT_69000 0x00c0 + +#define PCI_VENDOR_ID_MIRO 0x1031 +#define PCI_DEVICE_ID_MIRO_36050 0x5601 + +#define PCI_VENDOR_ID_NEC 0x1033 +#define PCI_DEVICE_ID_NEC_PCX2 0x0046 +#define PCI_DEVICE_ID_NEC_NILE4 0x005a + +#define PCI_VENDOR_ID_FD 0x1036 +#define PCI_DEVICE_ID_FD_36C70 0x0000 + +#define PCI_VENDOR_ID_SI 0x1039 +#define PCI_DEVICE_ID_SI_5591_AGP 0x0001 +#define PCI_DEVICE_ID_SI_6202 0x0002 +#define PCI_DEVICE_ID_SI_503 0x0008 +#define PCI_DEVICE_ID_SI_ACPI 0x0009 +#define PCI_DEVICE_ID_SI_5597_VGA 0x0200 +#define PCI_DEVICE_ID_SI_6205 0x0205 +#define PCI_DEVICE_ID_SI_501 0x0406 +#define PCI_DEVICE_ID_SI_496 0x0496 +#define PCI_DEVICE_ID_SI_300 0x0300 +#define PCI_DEVICE_ID_SI_530 0x0530 +#define PCI_DEVICE_ID_SI_540 0x0540 +#define PCI_DEVICE_ID_SI_540_VGA 0x5300 +#define PCI_DEVICE_ID_SI_601 0x0601 +#define PCI_DEVICE_ID_SI_620 0x0620 +#define PCI_DEVICE_ID_SI_630 0x0630 +#define PCI_DEVICE_ID_SI_730 0x0730 +#define PCI_DEVICE_ID_SI_630_VGA 0x6300 +#define PCI_DEVICE_ID_SI_730_VGA 0x7300 +#define PCI_DEVICE_ID_SI_5107 0x5107 +#define PCI_DEVICE_ID_SI_5300 0x5300 +#define PCI_DEVICE_ID_SI_5511 0x5511 +#define PCI_DEVICE_ID_SI_5513 0x5513 +#define PCI_DEVICE_ID_SI_5571 0x5571 +#define PCI_DEVICE_ID_SI_5591 0x5591 +#define PCI_DEVICE_ID_SI_5597 0x5597 +#define PCI_DEVICE_ID_SI_5598 0x5598 +#define PCI_DEVICE_ID_SI_5600 0x5600 +#define PCI_DEVICE_ID_SI_6300 0x6300 +#define PCI_DEVICE_ID_SI_6306 0x6306 +#define PCI_DEVICE_ID_SI_6326 0x6326 +#define PCI_DEVICE_ID_SI_7001 0x7001 + +#define PCI_VENDOR_ID_HP 0x103c +#define PCI_DEVICE_ID_HP_J2585A 0x1030 +#define PCI_DEVICE_ID_HP_J2585B 0x1031 + +#define PCI_VENDOR_ID_PCTECH 0x1042 +#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 +#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020 + +#define PCI_VENDOR_ID_ASUSTEK 0x1043 +#define PCI_DEVICE_ID_ASUSTEK_0675 0x0675 + +#define PCI_VENDOR_ID_DPT 0x1044 +#define PCI_DEVICE_ID_DPT 0xa400 + +#define PCI_VENDOR_ID_OPTI 0x1045 +#define PCI_DEVICE_ID_OPTI_92C178 0xc178 +#define PCI_DEVICE_ID_OPTI_82C557 0xc557 +#define PCI_DEVICE_ID_OPTI_82C558 0xc558 +#define PCI_DEVICE_ID_OPTI_82C621 0xc621 +#define PCI_DEVICE_ID_OPTI_82C700 0xc700 +#define PCI_DEVICE_ID_OPTI_82C701 0xc701 +#define PCI_DEVICE_ID_OPTI_82C814 0xc814 +#define PCI_DEVICE_ID_OPTI_82C822 0xc822 +#define PCI_DEVICE_ID_OPTI_82C861 0xc861 +#define PCI_DEVICE_ID_OPTI_82C825 0xd568 + +#define PCI_VENDOR_ID_ELSA 0x1048 +#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 +#define PCI_DEVICE_ID_ELSA_QS3000 0x3000 + +#define PCI_VENDOR_ID_SGS 0x104a +#define PCI_DEVICE_ID_SGS_2000 0x0008 +#define PCI_DEVICE_ID_SGS_1764 0x0009 + +#define PCI_VENDOR_ID_BUSLOGIC 0x104B +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 +#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 + +#define PCI_VENDOR_ID_TI 0x104c +#define PCI_DEVICE_ID_TI_TVP4010 0x3d04 +#define PCI_DEVICE_ID_TI_TVP4020 0x3d07 +#define PCI_DEVICE_ID_TI_1130 0xac12 +#define PCI_DEVICE_ID_TI_1031 0xac13 +#define PCI_DEVICE_ID_TI_1131 0xac15 +#define PCI_DEVICE_ID_TI_1250 0xac16 +#define PCI_DEVICE_ID_TI_1220 0xac17 +#define PCI_DEVICE_ID_TI_1221 0xac19 +#define PCI_DEVICE_ID_TI_1210 0xac1a +#define PCI_DEVICE_ID_TI_1450 0xac1b +#define PCI_DEVICE_ID_TI_1225 0xac1c +#define PCI_DEVICE_ID_TI_1251A 0xac1d +#define PCI_DEVICE_ID_TI_1211 0xac1e +#define PCI_DEVICE_ID_TI_1251B 0xac1f +#define PCI_DEVICE_ID_TI_1420 0xac51 + +#define PCI_VENDOR_ID_SONY 0x104d +#define PCI_DEVICE_ID_SONY_CXD3222 0x8039 + +#define PCI_VENDOR_ID_OAK 0x104e +#define PCI_DEVICE_ID_OAK_OTI107 0x0107 + +/* Winbond have two vendor IDs! See 0x10ad as well */ +#define PCI_VENDOR_ID_WINBOND2 0x1050 +#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 +#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a +#define PCI_DEVICE_ID_WINBOND2_6692 0x6692 + +#define PCI_VENDOR_ID_ANIGMA 0x1051 +#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100 + +#define PCI_VENDOR_ID_EFAR 0x1055 +#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 +#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 +#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462 +#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 + +#define PCI_VENDOR_ID_MOTOROLA 0x1057 +#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507 +#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 +#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 +#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 +#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802 +#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 +#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806 +#define PCI_DEVICE_ID_MOTOROLA_MPC190 0x6400 + +#define PCI_VENDOR_ID_PROMISE 0x105a +#define PCI_DEVICE_ID_PROMISE_20265 0x0d30 +#define PCI_DEVICE_ID_PROMISE_20267 0x4d30 +#define PCI_DEVICE_ID_PROMISE_20246 0x4d33 +#define PCI_DEVICE_ID_PROMISE_20262 0x4d38 +#define PCI_DEVICE_ID_PROMISE_5300 0x5300 + +#define PCI_VENDOR_ID_N9 0x105d +#define PCI_DEVICE_ID_N9_I128 0x2309 +#define PCI_DEVICE_ID_N9_I128_2 0x2339 +#define PCI_DEVICE_ID_N9_I128_T2R 0x493d + +#define PCI_VENDOR_ID_UMC 0x1060 +#define PCI_DEVICE_ID_UMC_UM8673F 0x0101 +#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 +#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a +#define PCI_DEVICE_ID_UMC_UM8886A 0x886a +#define PCI_DEVICE_ID_UMC_UM8881F 0x8881 +#define PCI_DEVICE_ID_UMC_UM8886F 0x8886 +#define PCI_DEVICE_ID_UMC_UM9017F 0x9017 +#define PCI_DEVICE_ID_UMC_UM8886N 0xe886 +#define PCI_DEVICE_ID_UMC_UM8891N 0xe891 + +#define PCI_VENDOR_ID_X 0x1061 +#define PCI_DEVICE_ID_X_AGX016 0x0001 + +#define PCI_VENDOR_ID_MYLEX 0x1069 +#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001 +#define PCI_DEVICE_ID_MYLEX_DAC960_PD 0x0002 +#define PCI_DEVICE_ID_MYLEX_DAC960_PG 0x0010 +#define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020 +#define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050 +#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 + +#define PCI_VENDOR_ID_PICOP 0x1066 +#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001 +#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002 + +#define PCI_VENDOR_ID_APPLE 0x106b +#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001 +#define PCI_DEVICE_ID_APPLE_GC 0x0002 +#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e +#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018 +#define PCI_DEVICE_ID_APPLE_KL_USB 0x0019 +#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 +#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021 + +#define PCI_VENDOR_ID_YAMAHA 0x1073 +#define PCI_DEVICE_ID_YAMAHA_724 0x0004 +#define PCI_DEVICE_ID_YAMAHA_724F 0x000d +#define PCI_DEVICE_ID_YAMAHA_740 0x000a +#define PCI_DEVICE_ID_YAMAHA_740C 0x000c +#define PCI_DEVICE_ID_YAMAHA_744 0x0010 +#define PCI_DEVICE_ID_YAMAHA_754 0x0012 + +#define PCI_VENDOR_ID_NEXGEN 0x1074 +#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78 + +#define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 +#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 +#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 +#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 + +#define PCI_VENDOR_ID_CYRIX 0x1078 +#define PCI_DEVICE_ID_CYRIX_5510 0x0000 +#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 +#define PCI_DEVICE_ID_CYRIX_5520 0x0002 +#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 +#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101 +#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 +#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 +#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 + +#define PCI_VENDOR_ID_LEADTEK 0x107d +#define PCI_DEVICE_ID_LEADTEK_805 0x0000 + +#define PCI_VENDOR_ID_INTERPHASE 0x107e +#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004 +#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005 +#define PCI_DEVICE_ID_INTERPHASE_5575 0x0008 + +#define PCI_VENDOR_ID_CONTAQ 0x1080 +#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 +#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693 + +#define PCI_VENDOR_ID_FOREX 0x1083 + +#define PCI_VENDOR_ID_OLICOM 0x108d +#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001 +#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011 +#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 +#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 +#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 +#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021 + +#define PCI_VENDOR_ID_SUN 0x108e +#define PCI_DEVICE_ID_SUN_EBUS 0x1000 +#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001 +#define PCI_DEVICE_ID_SUN_SIMBA 0x5000 +#define PCI_DEVICE_ID_SUN_PBM 0x8000 +#define PCI_DEVICE_ID_SUN_SABRE 0xa000 + +#define PCI_VENDOR_ID_CMD 0x1095 +#define PCI_DEVICE_ID_CMD_640 0x0640 +#define PCI_DEVICE_ID_CMD_643 0x0643 +#define PCI_DEVICE_ID_CMD_646 0x0646 +#define PCI_DEVICE_ID_CMD_647 0x0647 +#define PCI_DEVICE_ID_CMD_648 0x0648 +#define PCI_DEVICE_ID_CMD_649 0x0649 +#define PCI_DEVICE_ID_CMD_670 0x0670 + +#define PCI_VENDOR_ID_VISION 0x1098 +#define PCI_DEVICE_ID_VISION_QD8500 0x0001 +#define PCI_DEVICE_ID_VISION_QD8580 0x0002 + +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#define PCI_DEVICE_ID_BROOKTREE_848 0x0350 +#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351 +#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e +#define PCI_DEVICE_ID_BROOKTREE_878 0x0878 +#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474 + +#define PCI_VENDOR_ID_SIERRA 0x10a8 +#define PCI_DEVICE_ID_SIERRA_STB 0x0000 + +#define PCI_VENDOR_ID_SGI 0x10a9 +#define PCI_DEVICE_ID_SGI_IOC3 0x0003 + +#define PCI_VENDOR_ID_ACC 0x10aa +#define PCI_DEVICE_ID_ACC_2056 0x0000 + +#define PCI_VENDOR_ID_WINBOND 0x10ad +#define PCI_DEVICE_ID_WINBOND_83769 0x0001 +#define PCI_DEVICE_ID_WINBOND_82C105 0x0105 +#define PCI_DEVICE_ID_WINBOND_83C553 0x0565 + +#define PCI_VENDOR_ID_DATABOOK 0x10b3 +#define PCI_DEVICE_ID_DATABOOK_87144 0xb106 + +#define PCI_VENDOR_ID_PLX 0x10b5 +#define PCI_DEVICE_ID_PLX_R685 0x1030 +#define PCI_DEVICE_ID_PLX_ROMULUS 0x106a +#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076 +#define PCI_DEVICE_ID_PLX_1077 0x1077 +#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103 +#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 +#define PCI_DEVICE_ID_PLX_R753 0x1152 +#define PCI_DEVICE_ID_PLX_9050 0x9050 +#define PCI_DEVICE_ID_PLX_9060 0x9060 +#define PCI_DEVICE_ID_PLX_9060ES 0x906E +#define PCI_DEVICE_ID_PLX_9060SD 0x906D +#define PCI_DEVICE_ID_PLX_9080 0x9080 +#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 + +#define PCI_VENDOR_ID_MADGE 0x10b6 +#define PCI_DEVICE_ID_MADGE_MK2 0x0002 +#define PCI_DEVICE_ID_MADGE_C155S 0x1001 + +#define PCI_VENDOR_ID_3COM 0x10b7 +#define PCI_DEVICE_ID_3COM_3C985 0x0001 +#define PCI_DEVICE_ID_3COM_3C339 0x3390 +#define PCI_DEVICE_ID_3COM_3C590 0x5900 +#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 +#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 +#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 +#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 +#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 +#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 +#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 +#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 + +#define PCI_VENDOR_ID_SMC 0x10b8 +#define PCI_DEVICE_ID_SMC_EPIC100 0x0005 + +#define PCI_VENDOR_ID_AL 0x10b9 +#define PCI_DEVICE_ID_AL_M1445 0x1445 +#define PCI_DEVICE_ID_AL_M1449 0x1449 +#define PCI_DEVICE_ID_AL_M1451 0x1451 +#define PCI_DEVICE_ID_AL_M1461 0x1461 +#define PCI_DEVICE_ID_AL_M1489 0x1489 +#define PCI_DEVICE_ID_AL_M1511 0x1511 +#define PCI_DEVICE_ID_AL_M1513 0x1513 +#define PCI_DEVICE_ID_AL_M1521 0x1521 +#define PCI_DEVICE_ID_AL_M1523 0x1523 +#define PCI_DEVICE_ID_AL_M1531 0x1531 +#define PCI_DEVICE_ID_AL_M1533 0x1533 +#define PCI_DEVICE_ID_AL_M1541 0x1541 +#define PCI_DEVICE_ID_AL_M1543 0x1543 +#define PCI_DEVICE_ID_AL_M3307 0x3307 +#define PCI_DEVICE_ID_AL_M4803 0x5215 +#define PCI_DEVICE_ID_AL_M5219 0x5219 +#define PCI_DEVICE_ID_AL_M5229 0x5229 +#define PCI_DEVICE_ID_AL_M5237 0x5237 +#define PCI_DEVICE_ID_AL_M5243 0x5243 +#define PCI_DEVICE_ID_AL_M5451 0x5451 +#define PCI_DEVICE_ID_AL_M7101 0x7101 + +#define PCI_VENDOR_ID_MITSUBISHI 0x10ba + +#define PCI_VENDOR_ID_SURECOM 0x10bd +#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34 + +#define PCI_VENDOR_ID_NEOMAGIC 0x10c8 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083 + +#define PCI_VENDOR_ID_ASP 0x10cd +#define PCI_DEVICE_ID_ASP_ABP940 0x1200 +#define PCI_DEVICE_ID_ASP_ABP940U 0x1300 +#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300 + +#define PCI_VENDOR_ID_MACRONIX 0x10d9 +#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512 +#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531 + +#define PCI_VENDOR_ID_TCONRAD 0x10da +#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 + +#define PCI_VENDOR_ID_CERN 0x10dc +#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001 +#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002 +#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021 +#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022 + +#define PCI_VENDOR_ID_NVIDIA 0x10de +#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 +#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028 +#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029 +#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C +#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D +#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 +#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111 +#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152 +#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153 + +#define PCI_VENDOR_ID_IMS 0x10e0 +#define PCI_DEVICE_ID_IMS_8849 0x8849 + +#define PCI_VENDOR_ID_TEKRAM2 0x10e1 +#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c + +#define PCI_VENDOR_ID_TUNDRA 0x10e3 +#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000 + +#define PCI_VENDOR_ID_AMCC 0x10e8 +#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043 +#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062 +#define PCI_DEVICE_ID_AMCC_S5933 0x807d +#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c + +#define PCI_VENDOR_ID_INTERG 0x10ea +#define PCI_DEVICE_ID_INTERG_1680 0x1680 +#define PCI_DEVICE_ID_INTERG_1682 0x1682 +#define PCI_DEVICE_ID_INTERG_2000 0x2000 +#define PCI_DEVICE_ID_INTERG_2010 0x2010 +#define PCI_DEVICE_ID_INTERG_5000 0x5000 + +#define PCI_VENDOR_ID_REALTEK 0x10ec +#define PCI_DEVICE_ID_REALTEK_8029 0x8029 +#define PCI_DEVICE_ID_REALTEK_8129 0x8129 +#define PCI_DEVICE_ID_REALTEK_8139 0x8139 + +#define PCI_VENDOR_ID_TRUEVISION 0x10fa +#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c + +#define PCI_VENDOR_ID_INIT 0x1101 +#define PCI_DEVICE_ID_INIT_320P 0x9100 +#define PCI_DEVICE_ID_INIT_360P 0x9500 + +#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ +#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 + +#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */ +#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 + +#define PCI_VENDOR_ID_TTI 0x1103 +#define PCI_DEVICE_ID_TTI_HPT343 0x0003 +#define PCI_DEVICE_ID_TTI_HPT366 0x0004 + +#define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_DEVICE_ID_VIA_8363_0 0x0305 +#define PCI_DEVICE_ID_VIA_8371_0 0x0391 +#define PCI_DEVICE_ID_VIA_8501_0 0x0501 +#define PCI_DEVICE_ID_VIA_82C505 0x0505 +#define PCI_DEVICE_ID_VIA_82C561 0x0561 +#define PCI_DEVICE_ID_VIA_82C586_1 0x0571 +#define PCI_DEVICE_ID_VIA_82C576 0x0576 +#define PCI_DEVICE_ID_VIA_82C585 0x0585 +#define PCI_DEVICE_ID_VIA_82C586_0 0x0586 +#define PCI_DEVICE_ID_VIA_82C595 0x0595 +#define PCI_DEVICE_ID_VIA_82C596 0x0596 +#define PCI_DEVICE_ID_VIA_82C597_0 0x0597 +#define PCI_DEVICE_ID_VIA_82C598_0 0x0598 +#define PCI_DEVICE_ID_VIA_8601_0 0x0601 +#define PCI_DEVICE_ID_VIA_8605_0 0x0605 +#define PCI_DEVICE_ID_VIA_82C680 0x0680 +#define PCI_DEVICE_ID_VIA_82C686 0x0686 +#define PCI_DEVICE_ID_VIA_82C691 0x0691 +#define PCI_DEVICE_ID_VIA_82C693 0x0693 +#define PCI_DEVICE_ID_VIA_82C693_1 0x0698 +#define PCI_DEVICE_ID_VIA_82C926 0x0926 +#define PCI_DEVICE_ID_VIA_82C416 0x1571 +#define PCI_DEVICE_ID_VIA_82C595_97 0x1595 +#define PCI_DEVICE_ID_VIA_82C586_2 0x3038 +#define PCI_DEVICE_ID_VIA_82C586_3 0x3040 +#define PCI_DEVICE_ID_VIA_6305 0x3044 +#define PCI_DEVICE_ID_VIA_82C596_3 0x3050 +#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051 +#define PCI_DEVICE_ID_VIA_82C686_4 0x3057 +#define PCI_DEVICE_ID_VIA_82C686_5 0x3058 +#define PCI_DEVICE_ID_VIA_8233_5 0x3059 +#define PCI_DEVICE_ID_VIA_8233_7 0x3065 +#define PCI_DEVICE_ID_VIA_82C686_6 0x3068 +#define PCI_DEVICE_ID_VIA_8233_0 0x3074 +#define PCI_DEVICE_ID_VIA_8633_0 0x3091 +#define PCI_DEVICE_ID_VIA_8367_0 0x3099 +#define PCI_DEVICE_ID_VIA_86C100A 0x6100 +#define PCI_DEVICE_ID_VIA_8231 0x8231 +#define PCI_DEVICE_ID_VIA_8231_4 0x8235 +#define PCI_DEVICE_ID_VIA_8365_1 0x8305 +#define PCI_DEVICE_ID_VIA_8371_1 0x8391 +#define PCI_DEVICE_ID_VIA_8501_1 0x8501 +#define PCI_DEVICE_ID_VIA_82C597_1 0x8597 +#define PCI_DEVICE_ID_VIA_82C598_1 0x8598 +#define PCI_DEVICE_ID_VIA_8601_1 0x8601 +#define PCI_DEVICE_ID_VIA_8505_1 0X8605 +#define PCI_DEVICE_ID_VIA_8633_1 0xB091 +#define PCI_DEVICE_ID_VIA_8367_1 0xB099 + +#define PCI_VENDOR_ID_SMC2 0x1113 +#define PCI_DEVICE_ID_SMC2_1211TX 0x1211 + +#define PCI_VENDOR_ID_VORTEX 0x1119 +#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 +#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001 +#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002 +#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003 +#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004 +#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005 +#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006 +#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007 +#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008 +#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009 +#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a +#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b +#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c +#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125 + +#define PCI_VENDOR_ID_EF 0x111a +#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 +#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002 + +#define PCI_VENDOR_ID_IDT 0x111d +#define PCI_DEVICE_ID_IDT_IDT77201 0x0001 + +#define PCI_VENDOR_ID_FORE 0x1127 +#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210 +#define PCI_DEVICE_ID_FORE_PCA200E 0x0300 + +#define PCI_VENDOR_ID_IMAGINGTECH 0x112f +#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000 + +#define PCI_VENDOR_ID_PHILIPS 0x1131 +#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145 +#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146 + +#define PCI_VENDOR_ID_EICON 0x1133 +#define PCI_DEVICE_ID_EICON_DIVA20PRO 0xe001 +#define PCI_DEVICE_ID_EICON_DIVA20 0xe002 +#define PCI_DEVICE_ID_EICON_DIVA20PRO_U 0xe003 +#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004 +#define PCI_DEVICE_ID_EICON_DIVA201 0xe005 +#define PCI_DEVICE_ID_EICON_MAESTRA 0xe010 +#define PCI_DEVICE_ID_EICON_MAESTRAQ 0xe012 +#define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013 +#define PCI_DEVICE_ID_EICON_MAESTRAP 0xe014 + +#define PCI_VENDOR_ID_CYCLONE 0x113c +#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001 + +#define PCI_VENDOR_ID_ALLIANCE 0x1142 +#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210 +#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422 +#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424 +#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d + +#define PCI_VENDOR_ID_SYSKONNECT 0x1148 +#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000 +#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 +#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 + +#define PCI_VENDOR_ID_VMIC 0x114a +#define PCI_DEVICE_ID_VMIC_VME 0x7587 + +#define PCI_VENDOR_ID_DIGI 0x114f +#define PCI_DEVICE_ID_DIGI_EPC 0x0002 +#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003 +#define PCI_DEVICE_ID_DIGI_XEM 0x0004 +#define PCI_DEVICE_ID_DIGI_XR 0x0005 +#define PCI_DEVICE_ID_DIGI_CX 0x0006 +#define PCI_DEVICE_ID_DIGI_XRJ 0x0009 +#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a +#define PCI_DEVICE_ID_DIGI_XR_920 0x0027 +#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070 +#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 +#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 +#define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 + +#define PCI_VENDOR_ID_MUTECH 0x1159 +#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001 + +#define PCI_VENDOR_ID_RENDITION 0x1163 +#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001 +#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000 + +#define PCI_VENDOR_ID_SERVERWORKS 0x1166 +#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 +#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 +#define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010 +#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 + +#define PCI_VENDOR_ID_SBE 0x1176 +#define PCI_DEVICE_ID_SBE_WANXL100 0x0301 +#define PCI_DEVICE_ID_SBE_WANXL200 0x0302 +#define PCI_DEVICE_ID_SBE_WANXL400 0x0104 + +#define PCI_VENDOR_ID_TOSHIBA 0x1179 +#define PCI_DEVICE_ID_TOSHIBA_601 0x0601 +#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a +#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f + +#define PCI_VENDOR_ID_RICOH 0x1180 +#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 +#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466 +#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475 +#define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 +#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 + +#define PCI_VENDOR_ID_ARTOP 0x1191 +#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004 +#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 +#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006 +#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 +#define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002 +#define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010 +#define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020 +#define PCI_DEVICE_ID_ARTOP_AEC7612S 0x8030 +#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040 +#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050 +#define PCI_DEVICE_ID_ARTOP_8060 0x8060 + +#define PCI_VENDOR_ID_ZEITNET 0x1193 +#define PCI_DEVICE_ID_ZEITNET_1221 0x0001 +#define PCI_DEVICE_ID_ZEITNET_1225 0x0002 + +#define PCI_VENDOR_ID_OMEGA 0x119b +#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221 + +#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9 +#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 + +#define PCI_VENDOR_ID_GALILEO 0x11ab +#define PCI_DEVICE_ID_GALILEO_GT64011 0x4146 +#define PCI_DEVICE_ID_GALILEO_GT64111 0x4146 +#define PCI_DEVICE_ID_GALILEO_GT96100 0x9652 +#define PCI_DEVICE_ID_GALILEO_GT96100A 0x9653 + +#define PCI_VENDOR_ID_LITEON 0x11ad +#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002 + +#define PCI_VENDOR_ID_V3 0x11b0 +#define PCI_DEVICE_ID_V3_V960 0x0001 +#define PCI_DEVICE_ID_V3_V350 0x0001 +#define PCI_DEVICE_ID_V3_V961 0x0002 +#define PCI_DEVICE_ID_V3_V351 0x0002 + +#define PCI_VENDOR_ID_NP 0x11bc +#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001 + +#define PCI_VENDOR_ID_ATT 0x11c1 +#define PCI_DEVICE_ID_ATT_L56XMF 0x0440 +#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 + +#define PCI_VENDOR_ID_SPECIALIX 0x11cb +#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 +#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000 +#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 +#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004 + +#define PCI_VENDOR_ID_AURAVISION 0x11d1 +#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7 + +#define PCI_VENDOR_ID_IKON 0x11d5 +#define PCI_DEVICE_ID_IKON_10115 0x0115 +#define PCI_DEVICE_ID_IKON_10117 0x0117 + +#define PCI_VENDOR_ID_ZORAN 0x11de +#define PCI_DEVICE_ID_ZORAN_36057 0x6057 +#define PCI_DEVICE_ID_ZORAN_36120 0x6120 + +#define PCI_VENDOR_ID_KINETIC 0x11f4 +#define PCI_DEVICE_ID_KINETIC_2915 0x2915 + +#define PCI_VENDOR_ID_COMPEX 0x11f6 +#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112 +#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401 + +#define PCI_VENDOR_ID_RP 0x11fe +#define PCI_DEVICE_ID_RP32INTF 0x0001 +#define PCI_DEVICE_ID_RP8INTF 0x0002 +#define PCI_DEVICE_ID_RP16INTF 0x0003 +#define PCI_DEVICE_ID_RP4QUAD 0x0004 +#define PCI_DEVICE_ID_RP8OCTA 0x0005 +#define PCI_DEVICE_ID_RP8J 0x0006 +#define PCI_DEVICE_ID_RPP4 0x000A +#define PCI_DEVICE_ID_RPP8 0x000B +#define PCI_DEVICE_ID_RP8M 0x000C + +#define PCI_VENDOR_ID_CYCLADES 0x120e +#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 +#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101 +#define PCI_DEVICE_ID_CYCLOM_4Y_Lo 0x0102 +#define PCI_DEVICE_ID_CYCLOM_4Y_Hi 0x0103 +#define PCI_DEVICE_ID_CYCLOM_8Y_Lo 0x0104 +#define PCI_DEVICE_ID_CYCLOM_8Y_Hi 0x0105 +#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200 +#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201 +#define PCI_DEVICE_ID_PC300_RX_2 0x0300 +#define PCI_DEVICE_ID_PC300_RX_1 0x0301 +#define PCI_DEVICE_ID_PC300_TE_2 0x0310 +#define PCI_DEVICE_ID_PC300_TE_1 0x0311 + +#define PCI_VENDOR_ID_ESSENTIAL 0x120f +#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001 + +#define PCI_VENDOR_ID_O2 0x1217 +#define PCI_DEVICE_ID_O2_6729 0x6729 +#define PCI_DEVICE_ID_O2_6730 0x673a +#define PCI_DEVICE_ID_O2_6832 0x6832 +#define PCI_DEVICE_ID_O2_6836 0x6836 + +#define PCI_VENDOR_ID_3DFX 0x121a +#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 +#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002 +#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 +#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005 + +#define PCI_VENDOR_ID_SIGMADES 0x1236 +#define PCI_DEVICE_ID_SIGMADES_6425 0x6401 + +#define PCI_VENDOR_ID_CCUBE 0x123f + +#define PCI_VENDOR_ID_AVM 0x1244 +#define PCI_DEVICE_ID_AVM_B1 0x0700 +#define PCI_DEVICE_ID_AVM_C4 0x0800 +#define PCI_DEVICE_ID_AVM_A1 0x0a00 +#define PCI_DEVICE_ID_AVM_T1 0x1200 + +#define PCI_VENDOR_ID_DIPIX 0x1246 + +#define PCI_VENDOR_ID_STALLION 0x124d +#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000 +#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002 +#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003 + +#define PCI_VENDOR_ID_OPTIBASE 0x1255 +#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110 +#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210 +#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110 +#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120 +#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130 + +#define PCI_VENDOR_ID_ESS 0x125d +#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 +#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969 +#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 + +#define PCI_VENDOR_ID_SATSAGEM 0x1267 +#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016 +#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352 +#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b + +#define PCI_VENDOR_ID_HUGHES 0x1273 +#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002 + +#define PCI_VENDOR_ID_ENSONIQ 0x1274 +#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000 +#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 + +#define PCI_VENDOR_ID_ROCKWELL 0x127A + +#define PCI_VENDOR_ID_ITE 0x1283 +#define PCI_DEVICE_ID_ITE_IT8172G 0x8172 +#define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801 + +/* formerly Platform Tech */ +#define PCI_VENDOR_ID_ESS_OLD 0x1285 +#define PCI_DEVICE_ID_ESS_ESS0100 0x0100 + +#define PCI_VENDOR_ID_ALTEON 0x12ae +#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001 + +#define PCI_VENDOR_ID_USR 0x12B9 + +#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232 0x0003 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485 0x0004 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4 0x0005 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485 0x0006 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2 0x0007 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485 0x0008 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6 0x0009 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B + +#define PCI_VENDOR_ID_PICTUREL 0x12c5 +#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081 + +#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 +#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018 + +#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041 +#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D +#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001 +#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010 + +#define PCI_VENDOR_ID_AUREAL 0x12eb +#define PCI_DEVICE_ID_AUREAL_VORTEX_1 0x0001 +#define PCI_DEVICE_ID_AUREAL_VORTEX_2 0x0002 + +#define PCI_VENDOR_ID_CBOARDS 0x1307 +#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001 + +#define PCI_VENDOR_ID_SIIG 0x131f +#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000 +#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001 +#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_550 0x1010 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_650 0x1011 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_850 0x1012 +#define PCI_DEVICE_ID_SIIG_1P_10x 0x1020 +#define PCI_DEVICE_ID_SIIG_2P_10x 0x1021 +#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030 +#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031 +#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_550 0x1034 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_650 0x1035 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_850 0x1036 +#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050 +#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051 +#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052 +#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000 +#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001 +#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002 +#define PCI_DEVICE_ID_SIIG_1P_20x 0x2020 +#define PCI_DEVICE_ID_SIIG_2P_20x 0x2021 +#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030 +#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031 +#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_550 0x2040 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_650 0x2041 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_850 0x2042 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_550 0x2010 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_650 0x2011 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_850 0x2012 +#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050 +#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051 +#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 + +#define PCI_VENDOR_ID_DOMEX 0x134a +#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 + +#define PCI_VENDOR_ID_QUATECH 0x135C +#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 +#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 +#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030 +#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040 +#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 +#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 + +#define PCI_VENDOR_ID_SEALEVEL 0x135e +#define PCI_DEVICE_ID_SEALEVEL_U530 0x7101 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM2 0x7201 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM422 0x7402 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202 +#define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401 +#define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801 + +#define PCI_VENDOR_ID_HYPERCOPE 0x1365 +#define PCI_DEVICE_ID_HYPERCOPE_PLX 0x9050 +#define PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO 0x0104 +#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106 +#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 +#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 +#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS 0x0109 + +#define PCI_VENDOR_ID_LMC 0x1376 +#define PCI_DEVICE_ID_LMC_HSSI 0x0003 +#define PCI_DEVICE_ID_LMC_DS3 0x0004 +#define PCI_DEVICE_ID_LMC_SSI 0x0005 +#define PCI_DEVICE_ID_LMC_T1 0x0006 + +#define PCI_VENDOR_ID_NETGEAR 0x1385 +#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a + +#define PCI_VENDOR_ID_APPLICOM 0x1389 +#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001 +#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002 +#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003 + +#define PCI_VENDOR_ID_MOXA 0x1393 +#define PCI_DEVICE_ID_MOXA_C104 0x1040 +#define PCI_DEVICE_ID_MOXA_C168 0x1680 +#define PCI_DEVICE_ID_MOXA_CP204J 0x2040 +#define PCI_DEVICE_ID_MOXA_C218 0x2180 +#define PCI_DEVICE_ID_MOXA_C320 0x3200 + +#define PCI_VENDOR_ID_CCD 0x1397 +#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0 +#define PCI_DEVICE_ID_CCD_B000 0xb000 +#define PCI_DEVICE_ID_CCD_B006 0xb006 +#define PCI_DEVICE_ID_CCD_B007 0xb007 +#define PCI_DEVICE_ID_CCD_B008 0xb008 +#define PCI_DEVICE_ID_CCD_B009 0xb009 +#define PCI_DEVICE_ID_CCD_B00A 0xb00a +#define PCI_DEVICE_ID_CCD_B00B 0xb00b +#define PCI_DEVICE_ID_CCD_B00C 0xb00c +#define PCI_DEVICE_ID_CCD_B100 0xb100 + +#define PCI_VENDOR_ID_3WARE 0x13C1 +#define PCI_DEVICE_ID_3WARE_1000 0x1000 + +#define PCI_VENDOR_ID_ABOCOM 0x13D1 +#define PCI_DEVICE_ID_ABOCOM_2BD1 0x2BD1 + +#define PCI_VENDOR_ID_CMEDIA 0x13f6 +#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100 +#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101 +#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 +#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112 + +#define PCI_VENDOR_ID_LAVA 0x1407 +#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */ +#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */ +#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */ +#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */ +#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000 +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */ +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */ +#define PCI_DEVICE_ID_LAVA_BOCA_IOPPAR 0x8800 + +#define PCI_VENDOR_ID_TIMEDIA 0x1409 +#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168 + +#define PCI_VENDOR_ID_OXSEMI 0x1415 +#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 +#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A +#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 + +#define PCI_VENDOR_ID_AIRONET 0x14b9 +#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001 +#define PCI_DEVICE_ID_AIRONET_4800 0x4500 /* values switched? see */ +#define PCI_DEVICE_ID_AIRONET_4500 0x4800 /* drivers/net/aironet4500_card.c */ + +#define PCI_VENDOR_ID_TITAN 0x14D2 +#define PCI_DEVICE_ID_TITAN_100 0xA001 +#define PCI_DEVICE_ID_TITAN_200 0xA005 +#define PCI_DEVICE_ID_TITAN_400 0xA003 +#define PCI_DEVICE_ID_TITAN_800B 0xA004 + +#define PCI_VENDOR_ID_PANACOM 0x14d4 +#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 +#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402 + +#define PCI_VENDOR_ID_AFAVLAB 0x14db +#define PCI_DEVICE_ID_AFAVLAB_TK9902 0x2120 + +#define PCI_VENDOR_ID_SYBA 0x1592 +#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 +#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783 + +#define PCI_VENDOR_ID_MORETON 0x15aa +#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 + +#define PCI_VENDOR_ID_ZOLTRIX 0x15b0 +#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 + +#define PCI_VENDOR_ID_SYMPHONY 0x1c1c +#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 + +#define PCI_VENDOR_ID_TEKRAM 0x1de1 +#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 + +#define PCI_VENDOR_ID_3DLABS 0x3d3d +#define PCI_DEVICE_ID_3DLABS_300SX 0x0001 +#define PCI_DEVICE_ID_3DLABS_500TX 0x0002 +#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004 +#define PCI_DEVICE_ID_3DLABS_MX 0x0006 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007 +#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009 + +#define PCI_VENDOR_ID_AVANCE 0x4005 +#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064 +#define PCI_DEVICE_ID_AVANCE_2302 0x2302 + +#define PCI_VENDOR_ID_NETVIN 0x4a14 +#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 + +#define PCI_VENDOR_ID_S3 0x5333 +#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551 +#define PCI_DEVICE_ID_S3_ViRGE 0x5631 +#define PCI_DEVICE_ID_S3_TRIO 0x8811 +#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812 +#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814 +#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d +#define PCI_DEVICE_ID_S3_868 0x8880 +#define PCI_DEVICE_ID_S3_928 0x88b0 +#define PCI_DEVICE_ID_S3_864_1 0x88c0 +#define PCI_DEVICE_ID_S3_864_2 0x88c1 +#define PCI_DEVICE_ID_S3_964_1 0x88d0 +#define PCI_DEVICE_ID_S3_964_2 0x88d1 +#define PCI_DEVICE_ID_S3_968 0x88f0 +#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901 +#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902 +#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01 +#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10 +#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01 +#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02 +#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03 +#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 + +#define PCI_VENDOR_ID_DCI 0x6666 +#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 + +#define PCI_VENDOR_ID_GENROCO 0x5555 +#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 + +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_21145 0x0039 +#define PCI_DEVICE_ID_INTEL_21152BB 0xb152 +#define PCI_DEVICE_ID_INTEL_82375 0x0482 +#define PCI_DEVICE_ID_INTEL_82424 0x0483 +#define PCI_DEVICE_ID_INTEL_82378 0x0484 +#define PCI_DEVICE_ID_INTEL_82430 0x0486 +#define PCI_DEVICE_ID_INTEL_82434 0x04a3 +#define PCI_DEVICE_ID_INTEL_I960 0x0960 +#define PCI_DEVICE_ID_INTEL_82559 0x1030 +#define PCI_DEVICE_ID_INTEL_82559ER 0x1209 +#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 +#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222 +#define PCI_DEVICE_ID_INTEL_7116 0x1223 +#define PCI_DEVICE_ID_INTEL_82596 0x1226 +#define PCI_DEVICE_ID_INTEL_82865 0x1227 +#define PCI_DEVICE_ID_INTEL_82557 0x1229 +#define PCI_DEVICE_ID_INTEL_82437 0x122d +#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e +#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 +#define PCI_DEVICE_ID_INTEL_82371MX 0x1234 +#define PCI_DEVICE_ID_INTEL_82437MX 0x1235 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define PCI_DEVICE_ID_INTEL_82380FB 0x124b +#define PCI_DEVICE_ID_INTEL_82439 0x1250 +#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960 +#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 +#define PCI_DEVICE_ID_INTEL_82437VX 0x7030 +#define PCI_DEVICE_ID_INTEL_82439TX 0x7100 +#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 +#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 +#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 +#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 +#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 +#define PCI_DEVICE_ID_INTEL_82801AA_2 0x2412 +#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 +#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 +#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416 +#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418 +#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420 +#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421 +#define PCI_DEVICE_ID_INTEL_82801AB_2 0x2422 +#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423 +#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425 +#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426 +#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428 +#define PCI_DEVICE_ID_INTEL_82820FW_0 0x2440 +#define PCI_DEVICE_ID_INTEL_82820FW_1 0x2442 +#define PCI_DEVICE_ID_INTEL_82820FW_2 0x2443 +#define PCI_DEVICE_ID_INTEL_82820FW_3 0x2444 +#define PCI_DEVICE_ID_INTEL_82820FW_4 0x2449 +#define PCI_DEVICE_ID_INTEL_82820FW_5 0x244b +#define PCI_DEVICE_ID_INTEL_82820FW_6 0x244e +#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120 +#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121 +#define PCI_DEVICE_ID_INTEL_82810_MC3 0x7122 +#define PCI_DEVICE_ID_INTEL_82810_IG3 0x7123 +#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180 +#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181 +#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190 +#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191 +#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 +#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198 +#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199 +#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a +#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b +#define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600 +#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 +#define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602 +#define PCI_DEVICE_ID_INTEL_82372FB_3 0x7603 +#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 +#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 +#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca + +#define PCI_VENDOR_ID_COMPUTONE 0x8e0e +#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 +#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302 +#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e +#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003 + +#define PCI_VENDOR_ID_KTI 0x8e2e +#define PCI_DEVICE_ID_KTI_ET32P2 0x3000 + +#define PCI_VENDOR_ID_ADAPTEC 0x9004 +#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078 +#define PCI_DEVICE_ID_ADAPTEC_7821 0x2178 +#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860 +#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 +#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 +#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800 +#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038 +#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 +#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 +#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178 +#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078 +#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178 +#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278 +#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378 +#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478 +#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895 +#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078 +#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178 +#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278 +#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378 +#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478 +#define PCI_DEVICE_ID_ADAPTEC_7885 0x8578 +#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678 +#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778 +#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878 +#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78 + +#define PCI_VENDOR_ID_ADAPTEC2 0x9005 +#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010 +#define PCI_DEVICE_ID_ADAPTEC2_2930U2 0x0011 +#define PCI_DEVICE_ID_ADAPTEC2_7890B 0x0013 +#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f +#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050 +#define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051 +#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f +#define PCI_DEVICE_ID_ADAPTEC2_7892A 0x0080 +#define PCI_DEVICE_ID_ADAPTEC2_7892B 0x0081 +#define PCI_DEVICE_ID_ADAPTEC2_7892D 0x0083 +#define PCI_DEVICE_ID_ADAPTEC2_7892P 0x008f +#define PCI_DEVICE_ID_ADAPTEC2_7899A 0x00c0 +#define PCI_DEVICE_ID_ADAPTEC2_7899B 0x00c1 +#define PCI_DEVICE_ID_ADAPTEC2_7899D 0x00c3 +#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf + +#define PCI_VENDOR_ID_ATRONICS 0x907f +#define PCI_DEVICE_ID_ATRONICS_2015 0x2015 + +#define PCI_VENDOR_ID_HOLTEK 0x9412 +#define PCI_DEVICE_ID_HOLTEK_6565 0x6565 + +#define PCI_SUBVENDOR_ID_EXSYS 0xd84d +#define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014 + +#define PCI_VENDOR_ID_TIGERJET 0xe159 +#define PCI_DEVICE_ID_TIGERJET_300 0x0001 +#define PCI_DEVICE_ID_TIGERJET_100 0x0002 + +#define PCI_VENDOR_ID_ARK 0xedd8 +#define PCI_DEVICE_ID_ARK_STING 0xa091 +#define PCI_DEVICE_ID_ARK_STINGARK 0xa099 +#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 + +#define PCI_VENDOR_ID_MICROGATE 0x13c0 +#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 +#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 +#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 + +#define PCI_VENDOR_ID_SIS 0x1039 +#define PCI_DEVICE_ID_SIS_300 0x0300 +#define PCI_DEVICE_ID_SIS_540 0x5300 +#define PCI_DEVICE_ID_SIS_630 0x6300 + +#define PCI_VENDOR_ID_SMI 0x126f +#define PCI_DEVICE_ID_SMI_710 0x0710 +#define PCI_DEVICE_ID_SMI_712 0x0712 +#define PCI_DEVICE_ID_SMI_810 0x0810 diff --git a/include/video_ad7177.h b/include/video_ad7177.h new file mode 100644 index 0000000..68a6b8d --- /dev/null +++ b/include/video_ad7177.h @@ -0,0 +1,148 @@ +/* + * (C) Copyright 2000 + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it + * + * 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_AD7177_H_ +#define _VIDEO_AD7177_H_ + +/*#define VIDEO_DEBUG_DISABLE_COLORS 0 */ + +#define VIDEO_ENCODER_NAME "Analog Devices AD7177" + +#define VIDEO_ENCODER_I2C_RATE 100000 /* Max rate is 100Khz */ +#define VIDEO_ENCODER_CB_Y_CR_Y /* Use CB Y CR Y format... */ + +#define VIDEO_MODE_YUYV /* The only mode supported by this encoder */ +#undef VIDEO_MODE_RGB +#define VIDEO_MODE_BPP 16 + +#ifdef VIDEO_MODE_PAL +#define VIDEO_ACTIVE_COLS 720 +#define VIDEO_ACTIVE_ROWS 576 +#define VIDEO_VISIBLE_COLS 640 +#define VIDEO_VISIBLE_ROWS 480 +#endif + +#ifdef VIDEO_MODE_NTSC +#define VIDEO_ACTIVE_COLS 720 +#define VIDEO_ACTIVE_ROWS 525 +#define VIDEO_VISIBLE_COLS 640 +#define VIDEO_VISIBLE_ROWS 400 +#endif + +static unsigned char + video_encoder_data[] = { +#ifdef VIDEO_MODE_NTSC + 0x04, /* Mode Register 0 */ +#ifdef VIDEO_DEBUG_COLORBARS + 0xc2, +#else + 0x42, /* Mode Register 1 */ +#endif + 0x16, /* Subcarrier Freq 0 */ + 0x7c, /* Subcarrier Freq 1 */ + 0xf0, /* Subcarrier Freq 2 */ + 0x21, /* Subcarrier Freq 3 */ + 0x00, /* Subcarrier phase */ + 0x02, /* Timing Register 0 */ + 0x00, /* Extended Captioning 0 */ + 0x00, /* Extended Captioning 1 */ + 0x00, /* Closed Captioning 0 */ + 0x00, /* Closed Captioning 1 */ + 0x00, /* Timing Register 1 */ + 0x08, /* Mode Register 2 */ + 0x00, /* Pedestal Register 0 */ + 0x00, /* Pedestal Register 1 */ + 0x00, /* Pedestal Register 2 */ + 0x00, /* Pedestal Register 3 */ + 0x08 /* Mode Register 3 */ + +#endif +#ifdef VIDEO_MODE_PAL +#ifdef VIDEO_MODE_RGB_OUT + + 0x69, /* Mode Register 0 */ +#ifdef VIDEO_DEBUG_COLORBARS + 0xc0, /* Mode Register 1 (c0) */ +#else + 0x40, /* Mode Register 1 (c0) */ +#endif + 0xcb, /* Subcarrier Freq 0 */ + 0x8a, /* Subcarrier Freq 1 */ + 0x09, /* Subcarrier Freq 2 */ + 0x2a, /* Subcarrier Freq 3 */ + 0x00, /* Subcarrier phase */ + 0x02, /* Timing Register 0 */ + 0x00, /* Extended Captioning 0 */ + 0x00, /* Extended Captioning 1 */ + 0x00, /* Closed Captioning 0 */ + 0x00, /* Closed Captioning 1 */ + 0x00, /* Timing Register 1 */ + 0x28, /* Mode Register 2 */ + 0x00, /* Pedestal Register 0 */ + 0x00, /* Pedestal Register 1 */ + 0x00, /* Pedestal Register 2 */ + 0x00, /* Pedestal Register 3 */ + 0x08 /* Mode Register 3 */ + +#else + + 0x09, /* Mode Register 0 (was 01) */ +#ifdef VIDEO_DEBUG_COLORBARS + 0xd8, /* */ +#else + 0x59, /* Mode Register 1 (was 58) */ +#endif + 0xcb, /* Subcarrier Freq 0 */ + 0x8a, /* Subcarrier Freq 1 */ + 0x09, /* Subcarrier Freq 2 */ + 0x2a, /* Subcarrier Freq 3 */ + 0x00, /* Subcarrier phase */ + 0x02, /* Timing Register 0 (was a) */ + 0x00, /* Extended Captioning 0 */ + 0x00, /* Extended Captioning 1 */ + 0x00, /* Closed Captioning 0 */ + 0x00, /* Closed Captioning 1 */ + 0x00, /* Timing Register 1 */ +#ifdef VIDEO_DEBUG_LOWPOWER +#ifdef VIDEO_DEBUG_DISABLE_COLORS + 0x98, /* Mode Register 2 */ +#else + 0x88, /* Mode Register 2 */ +#endif +#else +#ifdef VIDEO_DEBUG_DISABLE_COLORS + 0x18, /* Mode Register 2 */ +#else + 0x08, /* Mode Register 2 */ +#endif +#endif + 0x00, /* Pedestal Register 0 */ + 0x00, /* Pedestal Register 1 */ + 0x00, /* Pedestal Register 2 */ + 0x00, /* Pedestal Register 3 */ + 0x08 /* Mode Register 3 */ +#endif +#endif + } ; + +#endif diff --git a/include/video_logo.h b/include/video_logo.h new file mode 100644 index 0000000..c12e8f8 --- /dev/null +++ b/include/video_logo.h @@ -0,0 +1,1951 @@ +/* */ +/* Generated by EasyLogo, (C) 2000 by Paolo Scaffardi */ +/* */ +/* To use this, include it and call: easylogo_plot(screen,&u_boot_logo, width,x,y) */ +/* */ +/* Where: 'screen' is the pointer to the frame buffer */ +/* 'width' is the screen width */ +/* 'x' is the horizontal position */ +/* 'y' is the vertical position */ +/* */ + +#include <video_easylogo.h> + +#define DEF_U_BOOT_LOGO_WIDTH 160 +#define DEF_U_BOOT_LOGO_HEIGHT 96 +#define DEF_U_BOOT_LOGO_PIXELS 15360 +#define DEF_U_BOOT_LOGO_BPP 16 +#define DEF_U_BOOT_LOGO_PIXEL_SIZE 2 +#define DEF_U_BOOT_LOGO_SIZE 30720 + +unsigned char DEF_U_BOOT_LOGO_DATA[DEF_U_BOOT_LOGO_SIZE] = { + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, + 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7c, 0x4b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7c, 0x69, 0x80, 0xd5, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xb6, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7c, 0x69, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa1, 0xa5, 0x70, 0xcc, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x6d, 0xc7, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x69, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0x96, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0x96, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x55, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xa0, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0x96, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x84, 0xdb, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x91, 0xc3, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xc0, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0x96, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7e, 0x96, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7d, 0x80, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xa0, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x75, 0xd1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0xdb, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x91, 0xc3, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0xa7, 0x9a, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x51, 0xa5, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x51, 0xa5, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x69, 0x7f, 0x8b, 0x7d, 0x75, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xb6, 0x80, 0xe1, 0x7e, 0xaa, 0x7c, 0x69, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xb6, + 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xb6, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0xdb, 0x8f, 0xc7, + 0x54, 0xa9, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x54, 0xa9, 0x8c, 0xcc, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7c, 0x69, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7d, 0x75, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xa0, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x89, 0xd1, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x59, 0xae, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x69, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xaa, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xc0, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7d, 0x80, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xd5, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xaa, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x89, 0xd1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x69, 0xc3, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x8f, 0xc7, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xd5, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x4b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x4c, 0x9f, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7c, 0x55, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xca, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x8c, 0xcc, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x9e, 0xa9, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa7, 0x9a, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa1, 0xa5, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0x96, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x9e, 0xa9, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x9e, 0xa9, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x8c, 0xcc, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xd5, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x4c, 0x9f, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x7c, 0xdb, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xca, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7e, 0x96, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xca, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0xa1, 0xa5, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa7, 0x9a, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7d, 0x80, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7c, 0xdb, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xca, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xd5, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7d, 0x80, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x7c, 0xdb, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x4c, 0x9f, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0x9d, 0xae, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xca, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0x96, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7d, 0x75, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xa0, + 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7d, 0x80, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0xdb, 0x97, 0xb8, + 0x51, 0xa5, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x51, 0xa5, 0x94, 0xbd, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7b, 0x60, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x7c, 0xdb, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7c, 0xdb, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x8c, 0xcc, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0xa7, 0x9a, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7b, 0x60, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x78, 0xd6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0xdb, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x4b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xc0, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7c, 0x4b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xd5, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0x8c, 0xcc, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x89, 0xd1, 0x45, 0x95, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7b, 0x60, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xb6, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xca, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x55, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa7, 0x9a, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xaa, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x75, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0xa9, 0x95, + 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0x84, 0xdb, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x8f, 0xc7, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, 0x45, 0x95, 0xa9, 0x95, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7c, 0x69, 0x7a, 0x3f, 0x7c, 0x4b, 0x7c, 0x69, + 0x7e, 0xaa, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7f, 0x8b, 0x7f, 0x8b, 0x7e, 0xaa, 0x80, 0xb6, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x75, 0xd1, 0x97, 0xb8, + 0x70, 0xcc, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x70, 0xcc, 0x97, 0xb8, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xb6, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7d, 0x80, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, + 0x80, 0xd5, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x69, 0x7c, 0x69, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x69, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x55, 0x7a, 0x3f, 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7b, 0x60, 0x7c, 0x69, 0x7b, 0x60, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7e, 0x96, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x7c, 0x69, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, + 0x7d, 0x80, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x7c, 0x4b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7e, 0xa0, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xca, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x55, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7d, 0x75, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x75, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xca, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x80, 0xb6, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x80, 0xb6, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xb6, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x80, 0xd5, 0x7c, 0x55, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0x96, 0x7a, 0x3f, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, + 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xb6, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x75, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7c, 0x69, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xb6, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x69, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7b, 0x60, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0x96, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xb6, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xa0, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7b, 0x60, 0x7a, 0x3f, 0x7e, 0xaa, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xa0, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7d, 0x80, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7d, 0x75, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x7f, 0x8b, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xd5, 0x7a, 0x3f, 0x7c, 0x55, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7c, 0x55, + 0x7c, 0x4b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xc0, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xaa, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x7d, 0x80, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7e, 0xaa, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xca, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xaa, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7b, 0x60, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7b, 0x60, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7c, 0x69, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x7e, 0x96, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xca, 0x7a, 0x3f, 0x7d, 0x75, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x69, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, + 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xaa, 0x7a, 0x3f, + 0x7c, 0x69, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xb6, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xc0, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x7c, 0x69, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7e, 0xaa, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xc0, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7b, 0x60, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x7b, 0x60, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7d, 0x80, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7f, 0x8b, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7b, 0x60, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xd5, 0x7a, 0x3f, 0x7d, 0x80, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7e, 0xaa, 0x7a, 0x3f, 0x7e, 0xa0, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7c, 0x4b, 0x7a, 0x3f, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7c, 0x4b, 0x7c, 0x69, + 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x7f, 0x8b, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, + 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x80, 0xe1, 0x7d, 0x80, 0x7a, 0x3f, 0x7a, 0x3f, + 0x7a, 0x3f, 0x7c, 0x69, 0x7b, 0x60, 0x7a, 0x3f, 0x7a, 0x3f, 0x7a, 0x3f, 0x80, 0xe1, 0x80, 0xe1 +}; + +fastimage_t u_boot_logo = { + DEF_U_BOOT_LOGO_DATA, + DEF_U_BOOT_LOGO_WIDTH, + DEF_U_BOOT_LOGO_HEIGHT, + DEF_U_BOOT_LOGO_BPP, + DEF_U_BOOT_LOGO_PIXEL_SIZE, + DEF_U_BOOT_LOGO_SIZE +}; diff --git a/lib_ppc/board.c b/lib_ppc/board.c new file mode 100644 index 0000000..347b663 --- /dev/null +++ b/lib_ppc/board.c @@ -0,0 +1,962 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <malloc.h> +#include <devices.h> +#include <syscall.h> +#ifdef CONFIG_8xx +#include <mpc8xx.h> +#endif +#if (CONFIG_COMMANDS & CFG_CMD_IDE) +#include <ide.h> +#endif +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) +#include <scsi.h> +#endif +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#include <kgdb.h> +#endif +#ifdef CONFIG_STATUS_LED +#include <status_led.h> +#endif +#include <net.h> +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +#include <cmd_bedbug.h> +#endif +#ifdef CFG_ALLOC_DPRAM +#include <commproc.h> +#endif +#include <version.h> +#if defined(CONFIG_BAB7xx) +#include <w83c553f.h> +#endif +#include <dtt.h> +#if defined(CONFIG_POST) +#include <post.h> +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_DOC) +void doc_init (void); +#endif +#if defined(CONFIG_HARD_I2C) || \ + defined(CONFIG_SOFT_I2C) +#include <i2c.h> +#endif + +static char *failed = "*** failed ***\n"; + +#if defined(CONFIG_PCU_E) || defined(CONFIG_OXC) +extern flash_info_t flash_info[]; +#endif + +#include <environment.h> + +#if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < CFG_MONITOR_BASE) || \ + (CFG_ENV_ADDR >= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)) ) || \ + defined(CFG_ENV_IS_IN_NVRAM) +#define TOTAL_MALLOC_LEN (CFG_MALLOC_LEN + CFG_ENV_SIZE) +#else +#define TOTAL_MALLOC_LEN CFG_MALLOC_LEN +#endif + +/* + * Begin and End of memory area for malloc(), and current "brk" + */ +static ulong mem_malloc_start = 0; +static ulong mem_malloc_end = 0; +static ulong mem_malloc_brk = 0; + +/************************************************************************ + * Utilities * + ************************************************************************ + */ + +/* + * The Malloc area is immediately below the monitor copy in DRAM + */ +static void mem_malloc_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + ulong dest_addr = CFG_MONITOR_BASE + gd->reloc_off; + + mem_malloc_end = dest_addr; + mem_malloc_start = dest_addr - TOTAL_MALLOC_LEN; + mem_malloc_brk = mem_malloc_start; + + memset ((void *) mem_malloc_start, + 0, + mem_malloc_end - mem_malloc_start); +} + +void *sbrk (ptrdiff_t increment) +{ + ulong old = mem_malloc_brk; + ulong new = old + increment; + + if ((new < mem_malloc_start) || (new > mem_malloc_end)) { + return (NULL); + } + mem_malloc_brk = new; + return ((void *) old); +} + +char *strmhz (char *buf, long hz) +{ + long l, n; + long m; + + n = hz / 1000000L; + l = sprintf (buf, "%ld", n); + m = (hz % 1000000L) / 1000L; + if (m != 0) + sprintf (buf + l, ".%03ld", m); + return (buf); +} + +static void syscalls_init (void) +{ + ulong *addr; + + syscall_tbl[SYSCALL_MALLOC] = (void *) malloc; + syscall_tbl[SYSCALL_FREE] = (void *) free; + + syscall_tbl[SYSCALL_INSTALL_HDLR] = (void *) irq_install_handler; + syscall_tbl[SYSCALL_FREE_HDLR] = (void *) irq_free_handler; + + addr = (ulong *) 0xc00; /* syscall ISR addr */ + + /* patch ISR code */ + *addr++ |= (ulong) syscall_tbl >> 16; + *addr++ |= (ulong) syscall_tbl & 0xFFFF; + *addr++ |= NR_SYSCALLS >> 16; + *addr++ |= NR_SYSCALLS & 0xFFFF; + + flush_cache (0x0C00, 0x10); +} + +/* + * All attempts to come up with a "common" initialization sequence + * that works for all boards and architectures failed: some of the + * requirements are just _too_ different. To get rid of the resulting + * mess of board dependend #ifdef'ed code we now make the whole + * initialization sequence configurable to the user. + * + * The requirements for any new initalization function is simple: it + * receives a pointer to the "global data" structure as it's only + * argument, and returns an integer return code, where 0 means + * "continue" and != 0 means "fatal error, hang the system". + */ +typedef int (init_fnc_t) (void); + +/************************************************************************ + * Init Utilities * + ************************************************************************ + * Some of this code should be moved into the core functions, + * but let's get it working (again) first... + */ + +static int init_baudrate (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + uchar tmp[64]; /* long enough for environment variables */ + int i = getenv_r ("baudrate", tmp, sizeof (tmp)); + + gd->baudrate = (i > 0) + ? (int) simple_strtoul (tmp, NULL, 10) + : CONFIG_BAUDRATE; + + return (0); +} + +/***********************************************************************/ + +static int init_func_ram (void) +{ + DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_BOARD_TYPES + int board_type = gd->board_type; +#else + int board_type = 0; /* use dummy arg */ +#endif + puts ("DRAM: "); + + if ((gd->ram_size = initdram (board_type)) > 0) { + print_size (gd->ram_size, "\n"); + return (0); + } + puts (failed); + return (1); +} + +/***********************************************************************/ + +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) +static int init_func_i2c (void) +{ + puts ("I2C: "); + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + puts ("ready\n"); + return (0); +} +#endif + +/***********************************************************************/ + +#if defined(CONFIG_WATCHDOG) +static int init_func_watchdog_init (void) +{ + puts (" Watchdog enabled\n"); + WATCHDOG_RESET (); + return (0); +} +# define INIT_FUNC_WATCHDOG_INIT init_func_watchdog_init, + +static int init_func_watchdog_reset (void) +{ + WATCHDOG_RESET (); + return (0); +} +# define INIT_FUNC_WATCHDOG_RESET init_func_watchdog_reset, +#else +# define INIT_FUNC_WATCHDOG_INIT /* undef */ +# define INIT_FUNC_WATCHDOG_RESET /* undef */ +#endif /* CONFIG_WATCHDOG */ + +/************************************************************************ + * Initialization sequence * + ************************************************************************ + */ + +init_fnc_t *init_sequence[] = { + +#if defined(CONFIG_BOARD_PRE_INIT) + board_pre_init, /* very early board init code (fpga boot, etc.) */ +#endif + + get_clocks, /* get CPU and bus clocks (etc.) */ + init_timebase, +#ifdef CFG_ALLOC_DPRAM + dpram_init, +#endif +#if defined(CONFIG_BOARD_POSTCLK_INIT) + board_postclk_init, +#endif + env_init, + init_baudrate, + serial_init, + console_init_f, + display_options, +#if defined(CONFIG_8260) + prt_8260_rsr, + prt_8260_clks, +#endif /* CONFIG_8260 */ + checkcpu, + checkboard, + INIT_FUNC_WATCHDOG_INIT +#if defined(CONFIG_BMW) || \ + defined(CONFIG_COGENT) || \ + defined(CONFIG_HYMOD) || \ + defined(CONFIG_RSD_PROTO) || \ + defined(CONFIG_W7O) + misc_init_f, +#endif + INIT_FUNC_WATCHDOG_RESET +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) + init_func_i2c, +#endif +#if defined(CONFIG_DTT) /* Digital Thermometers and Thermostats */ + dtt_init, +#endif + INIT_FUNC_WATCHDOG_RESET + init_func_ram, +#if defined(CFG_DRAM_TEST) + testdram, +#endif /* CFG_DRAM_TEST */ + INIT_FUNC_WATCHDOG_RESET + + NULL, /* Terminate this list */ +}; + +/************************************************************************ + * + * This is the first part of the initialization sequence that is + * implemented in C, but still running from ROM. + * + * The main purpose is to provide a (serial) console interface as + * soon as possible (so we can see any error messages), and to + * initialize the RAM so that we can relocate the monitor code to + * RAM. + * + * Be aware of the restrictions: global data is read-only, BSS is not + * initialized, and stack space is limited to a few kB. + * + ************************************************************************ + */ + +void board_init_f (ulong bootflag) +{ + DECLARE_GLOBAL_DATA_PTR; + + bd_t *bd; + ulong len, addr, addr_sp; + gd_t *id; + init_fnc_t **init_fnc_ptr; +#ifdef CONFIG_PRAM + int i; + ulong reg; + uchar tmp[64]; /* long enough for environment variables */ +#endif + + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); + +#ifndef CONFIG_8260 + /* Clear initial global data */ + memset ((void *) gd, 0, sizeof (gd_t)); +#endif + + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr) () != 0) { + hang (); + } + } + + /* + * Now that we have DRAM mapped and working, we can + * relocate the code and continue running from DRAM. + * + * Reserve memory at end of RAM for (top down in that order): + * - protected RAM + * - LCD framebuffer + * - monitor code + * - board info struct + */ + len = get_endaddr () - CFG_MONITOR_BASE; + + if (len > CFG_MONITOR_LEN) { + printf ("*** U-Boot size %ld > reserved memory (%d)\n", + len, CFG_MONITOR_LEN); + hang (); + } + + if (CFG_MONITOR_LEN > len) + len = CFG_MONITOR_LEN; + +#ifndef CONFIG_VERY_BIG_RAM + addr = CFG_SDRAM_BASE + gd->ram_size; +#else + /* only allow stack below 256M */ + addr = CFG_SDRAM_BASE + + (gd->ram_size > 256 << 20) ? 256 << 20 : gd->ram_size; +#endif + +#ifdef CONFIG_PRAM + /* + * reserve protected RAM + */ + i = getenv_r ("pram", tmp, sizeof (tmp)); + reg = (i > 0) ? simple_strtoul (tmp, NULL, 10) : CONFIG_PRAM; + addr -= (reg << 10); /* size is in kB */ +# ifdef DEBUG + printf ("Reserving %ldk for protected RAM at %08lx\n", reg, addr); +# endif +#endif /* CONFIG_PRAM */ + + /* round down to next 4 kB limit */ + addr &= ~(4096 - 1); +#ifdef DEBUG + printf ("Top of RAM usable for U-Boot at: %08lx\n", addr); +#endif + +#ifdef CONFIG_LCD + /* reserve memory for LCD display (always full pages) */ + addr = lcd_setmem (addr); + gd->fb_base = addr; +#endif /* CONFIG_LCD */ + +#if defined(CONFIG_VIDEO) && defined(CONFIG_8xx) + /* reserve memory for video display (always full pages) */ + addr = video_setmem (addr); + gd->fb_base = addr; +#endif /* CONFIG_VIDEO */ + + /* + * reserve memory for U-Boot code, data & bss + * round down to next 4 kB limit + */ + addr -= len; + addr &= ~(4096 - 1); + +#ifdef DEBUG + printf ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr); +#endif + + /* + * reserve memory for malloc() arena + */ + addr_sp = addr - TOTAL_MALLOC_LEN; +#ifdef DEBUG + printf ("Reserving %dk for malloc() at: %08lx\n", + TOTAL_MALLOC_LEN >> 10, addr_sp); +#endif + + /* + * (permanently) allocate a Board Info struct + * and a permanent copy of the "global" data + */ + addr_sp -= sizeof (bd_t); + bd = (bd_t *) addr_sp; + gd->bd = bd; +#ifdef DEBUG + printf ("Reserving %d Bytes for Board Info at: %08lx\n", + sizeof (bd_t), addr_sp); +#endif + addr_sp -= sizeof (gd_t); + id = (gd_t *) addr_sp; +#ifdef DEBUG + printf ("Reserving %d Bytes for Global Data at: %08lx\n", + sizeof (gd_t), addr_sp); +#endif + + /* + * Finally, we set up a new (bigger) stack. + * + * Leave some safety gap for SP, force alignment on 16 byte boundary + * Clear initial stack frame + */ + addr_sp -= 16; + addr_sp &= ~0xF; + *((ulong *) addr_sp)-- = 0; + *((ulong *) addr_sp)-- = 0; +#ifdef DEBUG + printf ("Stack Pointer at: %08lx\n", addr_sp); +#endif + + /* + * Save local variables to board info struct + */ + + bd->bi_memstart = CFG_SDRAM_BASE; /* start of DRAM memory */ + bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */ + +#ifdef CONFIG_IP860 + bd->bi_sramstart = SRAM_BASE; /* start of SRAM memory */ + bd->bi_sramsize = SRAM_SIZE; /* size of SRAM memory */ +#else + bd->bi_sramstart = 0; /* FIXME */ /* start of SRAM memory */ + bd->bi_sramsize = 0; /* FIXME */ /* size of SRAM memory */ +#endif + +#if defined(CONFIG_8xx) || defined(CONFIG_8260) + bd->bi_immr_base = CFG_IMMR; /* base of IMMR register */ +#endif + + bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */ + + WATCHDOG_RESET (); + bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */ + bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */ +#if defined(CONFIG_8260) + bd->bi_cpmfreq = gd->cpm_clk; + bd->bi_brgfreq = gd->brg_clk; + bd->bi_sccfreq = gd->scc_clk; + bd->bi_vco = gd->vco_out; +#endif /* CONFIG_8260 */ + + bd->bi_baudrate = gd->baudrate; /* Console Baudrate */ + +#ifdef CFG_EXTBDINFO + strncpy (bd->bi_s_version, "1.2", sizeof (bd->bi_s_version)); + strncpy (bd->bi_r_version, U_BOOT_VERSION, sizeof (bd->bi_r_version)); + + bd->bi_procfreq = gd->cpu_clk; /* Processor Speed, In Hz */ + bd->bi_plb_busfreq = gd->bus_clk; +#ifdef CONFIG_405GP + bd->bi_pci_busfreq = get_PCI_freq (); +#endif +#endif + +#ifdef DEBUG + printf ("New Stack Pointer is: %08lx\n", addr_sp); +#endif + + WATCHDOG_RESET (); + +#ifdef CONFIG_POST + post_bootmode_init(); + post_run (NULL, POST_ROM | post_bootmode_get(0)); +#endif + + WATCHDOG_RESET(); + + memcpy (id, gd, sizeof (gd_t)); + + relocate_code (addr_sp, id, addr); + + /* NOTREACHED - relocate_code() does not return */ +} + + +/************************************************************************ + * + * This is the next part if the initialization sequence: we are now + * running from RAM and have a "normal" C environment, i. e. global + * data can be written, BSS has been cleared, the stack size in not + * that critical any more, etc. + * + ************************************************************************ + */ + +void board_init_r (gd_t *id, ulong dest_addr) +{ + DECLARE_GLOBAL_DATA_PTR; + + cmd_tbl_t *cmdtp; + char *s, *e; + bd_t *bd; + int i; + extern void malloc_bin_reloc (void); +#ifndef CFG_ENV_IS_NOWHERE + extern char * env_name_spec; +#endif + +#ifndef CFG_NO_FLASH + ulong flash_size; +#endif + + gd = id; /* initialize RAM version of global data */ + bd = gd->bd; + + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + +#ifdef DEBUG + printf ("Now running in RAM - U-Boot at: %08lx\n", dest_addr); +#endif + + WATCHDOG_RESET (); + + gd->reloc_off = dest_addr - CFG_MONITOR_BASE; + + /* + * We have to relocate the command table manually + */ + for (cmdtp = &cmd_tbl[0]; cmdtp->name; cmdtp++) { + ulong addr; + + addr = (ulong) (cmdtp->cmd) + gd->reloc_off; +#if 0 + printf ("Command \"%s\": 0x%08lx => 0x%08lx\n", + cmdtp->name, (ulong) (cmdtp->cmd), addr); +#endif + cmdtp->cmd = + (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr; + + addr = (ulong)(cmdtp->name) + gd->reloc_off; + cmdtp->name = (char *)addr; + + if (cmdtp->usage) { + addr = (ulong)(cmdtp->usage) + gd->reloc_off; + cmdtp->usage = (char *)addr; + } +#ifdef CFG_LONGHELP + if (cmdtp->help) { + addr = (ulong)(cmdtp->help) + gd->reloc_off; + cmdtp->help = (char *)addr; + } +#endif + } + /* there are some other pointer constants we must deal with */ +#ifndef CFG_ENV_IS_NOWHERE + env_name_spec += gd->reloc_off; +#endif + + WATCHDOG_RESET (); + +#ifdef CONFIG_POST + post_reloc (); +#endif + + WATCHDOG_RESET(); + +#if defined(CONFIG_IP860) || defined(CONFIG_PCU_E) || defined (CONFIG_FLAGADM) + icache_enable (); /* it's time to enable the instruction cache */ +#endif + +#if defined(CONFIG_BAB7xx) + /* + * Do pci configuration on BAB 7xx _before_ the flash + * is initialised, because we need the ISA bridge there. + */ + pci_init (); + /* + * Initialise the ISA bridge + */ + initialise_w83c553f (); +#endif + + asm ("sync ; isync"); + + /* + * Setup trap handlers + */ + trap_init (dest_addr); + +#if !defined(CFG_NO_FLASH) + puts ("FLASH: "); + + if ((flash_size = flash_init ()) > 0) { +#ifdef CFG_FLASH_CHECKSUM + print_size (flash_size, ""); + /* + * Compute and print flash CRC if flashchecksum is set to 'y' + * + * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + */ + s = getenv ("flashchecksum"); + if (s && (*s == 'y')) { + printf (" CRC: %08lX", + crc32 (0, + (const unsigned char *) CFG_FLASH_BASE, + flash_size) + ); + } + putc ('\n'); +#else + print_size (flash_size, "\n"); +#endif /* CFG_FLASH_CHECKSUM */ + } else { + puts (failed); + hang (); + } + + bd->bi_flashstart = CFG_FLASH_BASE; /* update start of FLASH memory */ + bd->bi_flashsize = flash_size; /* size of FLASH memory (final value) */ +#if defined(CONFIG_PCU_E) || defined(CONFIG_OXC) + bd->bi_flashoffset = 0; +#elif CFG_MONITOR_BASE == CFG_FLASH_BASE + bd->bi_flashoffset = CFG_MONITOR_LEN; /* reserved area for startup monitor */ +#else + bd->bi_flashoffset = 0; +#endif +#else + + bd->bi_flashsize = 0; + bd->bi_flashstart = 0; + bd->bi_flashoffset = 0; +#endif /* !CFG_NO_FLASH */ + + WATCHDOG_RESET (); + + /* initialize higher level parts of CPU like time base and timers */ + cpu_init_r (); + + WATCHDOG_RESET (); + + /* initialize malloc() area */ + mem_malloc_init (); + malloc_bin_reloc (); + +#ifdef CONFIG_SPI +# if !defined(CFG_ENV_IS_IN_EEPROM) + spi_init_f (); +# endif + spi_init_r (); +#endif + + /* relocate environment function pointers etc. */ + env_relocate (); + + /* + * Fill in missing fields of bd_info. + * We do this here, where we have "normal" access to the + * environment; we used to do this still running from ROM, + * where had to use getenv_r(), which can be pretty slow when + * the environment is in EEPROM. + */ + s = getenv ("ethaddr"); +#if defined (CONFIG_MBX) || defined (CONFIG_RPXCLASSIC) || defined(CONFIG_IAD210) + if (s == NULL) + board_get_enetaddr (bd->bi_enetaddr); + else +#endif + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } +#ifdef CONFIG_HERMES + if ((gd->board_type >> 16) == 2) + bd->bi_ethspeed = gd->board_type & 0xFFFF; + else + bd->bi_ethspeed = 0xFFFF; +#endif + +#ifdef CONFIG_NX823 + load_sernum_ethaddr (); +#endif + +#if defined(CFG_GT_6426x) || defined(CONFIG_PN62) + /* handle the 2nd ethernet address */ + + s = getenv ("eth1addr"); + + for (i = 0; i < 6; ++i) { + bd->bi_enet1addr[i] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } +#endif +#if defined(CFG_GT_6426x) + /* handle the 3rd ethernet address */ + + s = getenv ("eth2addr"); + + for (i = 0; i < 6; ++i) { + bd->bi_enet2addr[i] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } +#endif + + +#if defined(CONFIG_TQM8xxL) || defined(CONFIG_TQM8260) || \ + defined(CONFIG_CCM) + load_sernum_ethaddr (); +#endif + /* IP Address */ + bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + + WATCHDOG_RESET (); + +#if defined(CONFIG_PCI) && !defined(CONFIG_BAB7xx) + /* + * Do pci configuration + */ + pci_init (); +#endif + +/** leave this here (after malloc(), environment and PCI are working) **/ + /* Initialize devices */ + devices_init (); + + /* allocate syscalls table (console_init_r will fill it in */ + syscall_tbl = (void **) malloc (NR_SYSCALLS * sizeof (void *)); + + /* Initialize the console (after the relocation and devices init) */ + console_init_r (); +/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ + syscalls_init (); + +#if defined(CONFIG_CCM) || \ + defined(CONFIG_COGENT) || \ + defined(CONFIG_CPCI405) || \ + defined(CONFIG_EVB64260) || \ + defined(CONFIG_HYMOD) || \ + defined(CONFIG_LWMON) || \ + defined(CONFIG_PCU_E) || \ + defined(CONFIG_W7O) || \ + defined(CONFIG_MISC_INIT_R) + /* miscellaneous platform dependent initialisations */ + misc_init_r (); +#endif + +#ifdef CONFIG_HERMES + if (bd->bi_ethspeed != 0xFFFF) + hermes_start_lxt980 ((int) bd->bi_ethspeed); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && ( \ + defined(CONFIG_CCM) || \ + defined(CONFIG_EP8260) || \ + defined(CONFIG_IP860) || \ + defined(CONFIG_IVML24) || \ + defined(CONFIG_IVMS8) || \ + defined(CONFIG_LWMON) || \ + defined(CONFIG_MPC8260ADS) || \ + defined(CONFIG_PCU_E) || \ + defined(CONFIG_RPXSUPER) || \ + defined(CONFIG_SPD823TS) ) + + WATCHDOG_RESET (); +# ifdef DEBUG + puts ("Reset Ethernet PHY\n"); +# endif + reset_phy (); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + WATCHDOG_RESET (); + puts ("KGDB: "); + kgdb_init (); +#endif + +#ifdef DEBUG + printf ("U-Boot relocated to %08lx\n", dest_addr); +#endif + + /* + * Enable Interrupts + */ + interrupt_init (); + + /* Must happen after interrupts are initialized since + * an irq handler gets installed + */ +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO + serial_buffered_init(); +#endif + +#ifdef CONFIG_STATUS_LED + status_led_set (STATUS_LED_BOOT, STATUS_LED_BLINKING); +#endif + + udelay (20); + + set_timer (0); + + /* Insert function pointers now that we have relocated the code */ + + /* Initialize from environment */ + if ((s = getenv ("loadaddr")) != NULL) { + load_addr = simple_strtoul (s, NULL, 16); + } +#if (CONFIG_COMMANDS & CFG_CMD_NET) + if ((s = getenv ("bootfile")) != NULL) { + copy_filename (BootFile, s, sizeof (BootFile)); + } +#endif /* CFG_CMD_NET */ + + WATCHDOG_RESET (); + +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) + WATCHDOG_RESET (); + puts ("SCSI: "); + scsi_init (); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_DOC) + WATCHDOG_RESET (); + puts ("DOC: "); + doc_init (); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) + WATCHDOG_RESET (); + puts ("Net: "); + eth_initialize (bd); +#endif + +#ifdef CONFIG_POST + post_run (NULL, POST_RAM | post_bootmode_get(0)); + if (post_bootmode_get(0) & POST_POWERFAIL) { + post_bootmode_clear(); + board_poweroff(); + } +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) && !(CONFIG_COMMANDS & CFG_CMD_IDE) + WATCHDOG_RESET (); + puts ("PCMCIA:"); + pcmcia_init (); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_IDE) + WATCHDOG_RESET (); +# ifdef CONFIG_IDE_8xx_PCCARD + puts ("PCMCIA:"); +# else + puts ("IDE: "); +#endif + ide_init (); +#endif /* CFG_CMD_IDE */ + +#ifdef CONFIG_LAST_STAGE_INIT + WATCHDOG_RESET (); + /* + * Some parts can be only initialized if all others (like + * Interrupts) are up and running (i.e. the PC-style ISA + * keyboard). + */ + last_stage_init (); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) + WATCHDOG_RESET (); + bedbug_init (); +#endif + +#ifdef CONFIG_PRAM + /* + * Export available size of memory for Linux, + * taking into account the protected RAM at top of memory + */ + { + ulong pram; + char *s; + uchar memsz[32]; + + if ((s = getenv ("pram")) != NULL) { + pram = simple_strtoul (s, NULL, 10); + } else { + pram = CONFIG_PRAM; + } + sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram); + setenv ("mem", memsz); + } +#endif + + /* Initialization complete - start the monitor */ + + /* main_loop() can return to retry autoboot, if so just run it again. */ + for (;;) { + WATCHDOG_RESET (); + main_loop (); + } + + /* NOTREACHED - no way out of command loop except booting */ +} + +void hang (void) +{ + puts ("### ERROR ### Please RESET the board ###\n"); + for (;;); +} + +#if 0 /* We could use plain global data, but the resulting code is bigger */ +/* + * Pointer to initial global data area + * + * Here we initialize it. + */ +#undef XTRN_DECLARE_GLOBAL_DATA_PTR +#define XTRN_DECLARE_GLOBAL_DATA_PTR /* empty = allocate here */ +DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); +#endif /* 0 */ + +/************************************************************************/ diff --git a/lib_ppc/extable.c b/lib_ppc/extable.c new file mode 100644 index 0000000..2f90df0 --- /dev/null +++ b/lib_ppc/extable.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +extern const struct exception_table_entry __start___ex_table[]; +extern const struct exception_table_entry __stop___ex_table[]; + +static inline unsigned long +search_one_table(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) +{ + while (first <= last) { + const struct exception_table_entry *mid; + long diff; + + mid = (last - first) / 2 + first; + diff = mid->insn - value; + if (diff == 0) + return mid->fixup; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return 0; +} + +int ex_tab_message = 1; + +unsigned long +search_exception_table(unsigned long addr) +{ + unsigned long ret; + + /* There is only the kernel to search. */ + ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); + if (ex_tab_message) + printf("Bus Fault @ 0x%08lx, fixup 0x%08lx\n", addr, ret); + if (ret) return ret; + + return 0; +} diff --git a/net/tftp.c b/net/tftp.c new file mode 100644 index 0000000..0ad244f --- /dev/null +++ b/net/tftp.c @@ -0,0 +1,326 @@ +/* + * Copyright 1994, 1995, 2000 Neil Russell. + * (See License) + * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de + */ + +#include <common.h> +#include <command.h> +#include <net.h> +#include "tftp.h" +#include "bootp.h" + +#undef ET_DEBUG + +#if (CONFIG_COMMANDS & CFG_CMD_NET) + +#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */ +#define TIMEOUT 2 /* Seconds to timeout for a lost pkt */ +#ifndef CONFIG_NET_RETRY_COUNT +# define TIMEOUT_COUNT 10 /* # of timeouts before giving up */ +#else +# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT * 2) +#endif + /* (for checking the image size) */ +#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ + +/* + * TFTP operations. + */ +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 + + +static int TftpServerPort; /* The UDP port at their end */ +static int TftpOurPort; /* The UDP port at our end */ +static int TftpTimeoutCount; +static unsigned TftpBlock; +static unsigned TftpLastBlock; +static int TftpState; +#define STATE_RRQ 1 +#define STATE_DATA 2 +#define STATE_TOO_LARGE 3 +#define STATE_BAD_MAGIC 4 + +#define DEFAULT_NAME_LEN (8 + 4 + 1) +static char default_filename[DEFAULT_NAME_LEN]; +static char *tftp_filename; + +#ifdef CFG_DIRECT_FLASH_TFTP +extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; +#endif + +static __inline__ void +store_block (unsigned block, uchar * src, unsigned len) +{ + ulong offset = block * 512, newsize = offset + len; +#ifdef CFG_DIRECT_FLASH_TFTP + int i, rc = 0; + + for (i=0; i<CFG_MAX_FLASH_BANKS; i++) { + /* start address in flash? */ + if (load_addr + offset >= flash_info[i].start[0]) { + rc = 1; + break; + } + } + + if (rc) { /* Flash is destination for this packet */ + rc = flash_write ((uchar *)src, (ulong)(load_addr+offset), len); + if (rc) { + flash_perror (rc); + NetState = NETLOOP_FAIL; + return; + } + } + else +#endif /* CFG_DIRECT_FLASH_TFTP */ + { + (void)memcpy((void *)(load_addr + offset), src, len); + } + + if (NetBootFileXferSize < newsize) + NetBootFileXferSize = newsize; +} + +static void TftpSend (void); +static void TftpTimeout (void); + +/**********************************************************************/ + +static void +TftpSend (void) +{ + volatile uchar * pkt; + volatile uchar * xp; + int len = 0; + + /* + * We will always be sending some sort of packet, so + * cobble together the packet headers now. + */ + pkt = NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE; + + switch (TftpState) { + + case STATE_RRQ: + xp = pkt; + *((ushort *)pkt)++ = htons(TFTP_RRQ); + strcpy ((char *)pkt, tftp_filename); + pkt += strlen(tftp_filename) + 1; + strcpy ((char *)pkt, "octet"); + pkt += 5 /*strlen("octet")*/ + 1; + len = pkt - xp; + break; + + case STATE_DATA: + xp = pkt; + *((ushort *)pkt)++ = htons(TFTP_ACK); + *((ushort *)pkt)++ = htons(TftpBlock); + len = pkt - xp; + break; + + case STATE_TOO_LARGE: + xp = pkt; + *((ushort *)pkt)++ = htons(TFTP_ERROR); + *((ushort *)pkt)++ = htons(3); + strcpy ((char *)pkt, "File too large"); + pkt += 14 /*strlen("File too large")*/ + 1; + len = pkt - xp; + break; + + case STATE_BAD_MAGIC: + xp = pkt; + *((ushort *)pkt)++ = htons(TFTP_ERROR); + *((ushort *)pkt)++ = htons(2); + strcpy ((char *)pkt, "File has bad magic"); + pkt += 18 /*strlen("File has bad magic")*/ + 1; + len = pkt - xp; + break; + } + + NetSetEther (NetTxPacket, NetServerEther, PROT_IP); + NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP, + TftpServerPort, TftpOurPort, len); + NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); +} + + +static void +TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) +{ + ushort proto; + + if (dest != TftpOurPort) { + return; + } + if (TftpState != STATE_RRQ && src != TftpServerPort) { + return; + } + + if (len < 2) { + return; + } + len -= 2; + /* warning: don't use increment (++) in ntohs() macros!! */ + proto = *((ushort *)pkt)++; + switch (ntohs(proto)) { + + case TFTP_RRQ: + case TFTP_WRQ: + case TFTP_ACK: + break; + default: + break; + + case TFTP_DATA: + if (len < 2) + return; + len -= 2; + TftpBlock = ntohs(*(ushort *)pkt); + if (((TftpBlock - 1) % 10) == 0) { + putc ('#'); + } else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) { + puts ("\n\t "); + } + + if (TftpState == STATE_RRQ) { + TftpState = STATE_DATA; + TftpServerPort = src; + TftpLastBlock = 0; + + if (TftpBlock != 1) { /* Assertion */ + printf ("\nTFTP error: " + "First block is not block 1 (%d)\n" + "Starting again\n\n", + TftpBlock); + NetStartAgain (); + break; + } + } + + if (TftpBlock == TftpLastBlock) { + /* + * Same block again; ignore it. + */ + break; + } + + TftpLastBlock = TftpBlock; + NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); + + store_block (TftpBlock - 1, pkt + 2, len); + + /* + * Acknoledge the block just received, which will prompt + * the server for the next one. + */ + TftpSend (); + + if (len < 512) { + /* + * We received the whole thing. Try to + * run it. + */ + puts ("\ndone\n"); + NetState = NETLOOP_SUCCESS; + } + break; + + case TFTP_ERROR: + printf ("\nTFTP error: '%s' (%d)\n", + pkt + 2, ntohs(*(ushort *)pkt)); + puts ("Starting again\n\n"); + NetStartAgain (); + break; + } +} + + +static void +TftpTimeout (void) +{ + if (++TftpTimeoutCount >= TIMEOUT_COUNT) { + puts ("\nRetry count exceeded; starting again\n"); + NetStartAgain (); + } else { + puts ("T "); + NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); + TftpSend (); + } +} + + +void +TftpStart (void) +{ +#ifdef ET_DEBUG + printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", + NetServerEther[0], + NetServerEther[1], + NetServerEther[2], + NetServerEther[3], + NetServerEther[4], + NetServerEther[5] + ); +#endif /* DEBUG */ + + if (BootFile[0] == '\0') { + IPaddr_t OurIP = ntohl(NetOurIP); + + sprintf(default_filename, "%02lX%02lX%02lX%02lX.img", + OurIP & 0xFF, + (OurIP >> 8) & 0xFF, + (OurIP >> 16) & 0xFF, + (OurIP >> 24) & 0xFF ); + tftp_filename = default_filename; + + printf ("*** Warning: no boot file name; using '%s'\n", + tftp_filename); + } else { + tftp_filename = BootFile; + } + + puts ("TFTP from server "); print_IPaddr (NetServerIP); + puts ("; our IP address is "); print_IPaddr (NetOurIP); + + /* Check if we need to send across this subnet */ + if (NetOurGatewayIP && NetOurSubnetMask) { + IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; + IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; + + if (OurNet != ServerNet) { + puts ("; sending through gateway "); + print_IPaddr (NetOurGatewayIP) ; + } + } + putc ('\n'); + + printf ("Filename '%s'.", tftp_filename); + + if (NetBootFileSize) { + printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9); + print_size (NetBootFileSize<<9, ""); + } + + putc ('\n'); + + printf ("Load address: 0x%lx\n", load_addr); + + puts ("Loading: *\b"); + + NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); + NetSetHandler (TftpHandler); + + TftpServerPort = WELL_KNOWN_PORT; + TftpTimeoutCount = 0; + TftpState = STATE_RRQ; + TftpOurPort = 1024 + (get_timer(0) % 3072); + + TftpSend (); +} + +#endif /* CFG_CMD_NET */ diff --git a/rtc/ds1302.c b/rtc/ds1302.c new file mode 100644 index 0000000..ec5616a --- /dev/null +++ b/rtc/ds1302.c @@ -0,0 +1,327 @@ +/* + * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip + * + * Rex G. Feany <rfeany@zumanetworks.com> + * + */ + +#include <common.h> +#include <command.h> +#include <rtc.h> + +#if defined(CONFIG_RTC_DS1302) && (CONFIG_COMMANDS & CFG_CMD_DATE) + +/* GPP Pins */ +#define DATA 0x200 +#define SCLK 0x400 +#define RST 0x800 + +/* Happy Fun Defines(tm) */ +#define RESET rtc_go_low(RST), rtc_go_low(SCLK) +#define N_RESET rtc_go_high(RST), rtc_go_low(SCLK) + +#define CLOCK_HIGH rtc_go_high(SCLK) +#define CLOCK_LOW rtc_go_low(SCLK) + +#define DATA_HIGH rtc_go_high(DATA) +#define DATA_LOW rtc_go_low(DATA) +#define DATA_READ (GTREGREAD(GPP_VALUE) & DATA) + +#undef RTC_DEBUG + +#ifdef RTC_DEBUG +# define DPRINTF(x,args...) printf("ds1302: " x , ##args) +static inline void DUMP(const char *ptr, int num) +{ + while (num--) printf("%x ", *ptr++); + printf("]\n"); +} +#else +# define DPRINTF(x,args...) +# define DUMP(ptr, num) +#endif + +/* time data format for DS1302 */ +struct ds1302_st +{ + unsigned char CH:1; /* clock halt 1=stop 0=start */ + unsigned char sec10:3; + unsigned char sec:4; + + unsigned char zero0:1; + unsigned char min10:3; + unsigned char min:4; + + unsigned char fmt:1; /* 1=12 hour 0=24 hour */ + unsigned char zero1:1; + unsigned char hr10:2; /* 10 (0-2) or am/pm (am/pm, 0-1) */ + unsigned char hr:4; + + unsigned char zero2:2; + unsigned char date10:2; + unsigned char date:4; + + unsigned char zero3:3; + unsigned char month10:1; + unsigned char month:4; + + unsigned char zero4:5; + unsigned char day:3; /* day of week */ + + unsigned char year10:4; + unsigned char year:4; + + unsigned char WP:1; /* write protect 1=protect 0=unprot */ + unsigned char zero5:7; +}; + +static int ds1302_initted=0; + +/* Pin control */ +static inline void +rtc_go_high(unsigned int mask) +{ + unsigned int f = GTREGREAD(GPP_VALUE) | mask; + + GT_REG_WRITE(GPP_VALUE, f); +} + +static inline void +rtc_go_low(unsigned int mask) +{ + unsigned int f = GTREGREAD(GPP_VALUE) & ~mask; + + GT_REG_WRITE(GPP_VALUE, f); +} + +static inline void +rtc_go_input(unsigned int mask) +{ + unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask; + + GT_REG_WRITE(GPP_IO_CONTROL, f); +} + +static inline void +rtc_go_output(unsigned int mask) +{ + unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask; + + GT_REG_WRITE(GPP_IO_CONTROL, f); +} + +/* Access data in RTC */ + +static void +write_byte(unsigned char b) +{ + int i; + unsigned char mask=1; + + for(i=0;i<8;i++) { + CLOCK_LOW; /* Lower clock */ + (b&mask)?DATA_HIGH:DATA_LOW; /* set data */ + udelay(1); + CLOCK_HIGH; /* latch data with rising clock */ + udelay(1); + mask=mask<<1; + } +} + +static unsigned char +read_byte(void) +{ + int i; + unsigned char mask=1; + unsigned char b=0; + + for(i=0;i<8;i++) { + CLOCK_LOW; + udelay(1); + if (DATA_READ) b|=mask; /* if this bit is high, set in b */ + CLOCK_HIGH; /* clock out next bit */ + udelay(1); + mask=mask<<1; + } + return b; +} + +static void +read_ser_drv(unsigned char addr, unsigned char *buf, int count) +{ + int i; +#ifdef RTC_DEBUG + char *foo = buf; +#endif + + DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr); + + addr|=1; /* READ */ + N_RESET; + udelay(4); + write_byte(addr); + rtc_go_input(DATA); /* Put gpp pin into input mode */ + udelay(1); + for(i=0;i<count;i++) *(buf++)=read_byte(); + RESET; + rtc_go_output(DATA);/* Reset gpp for output */ + udelay(4); + + DUMP(foo, count); +} + +static void +write_ser_drv(unsigned char addr, unsigned char *buf, int count) +{ + int i; + + DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr); + DUMP(buf, count); + + addr&=~1; /* WRITE */ + N_RESET; + udelay(4); + write_byte(addr); + for(i=0;i<count;i++) write_byte(*(buf++)); + RESET; + udelay(4); + +} + +void +rtc_init(void) +{ + struct ds1302_st bbclk; + unsigned char b; + int mod; + + DPRINTF("init\n"); + + rtc_go_output(DATA|SCLK|RST); + + /* disable write protect */ + b = 0; + write_ser_drv(0x8e,&b,1); + + /* enable trickle */ + b = 0xa5; /* 1010.0101 */ + write_ser_drv(0x90,&b,1); + + /* read burst */ + read_ser_drv(0xbe, (unsigned char *)&bbclk, 8); + + /* Sanity checks */ + mod = 0; + if (bbclk.CH) { + printf("ds1302: Clock was halted, starting clock\n"); + bbclk.CH=0; + mod=1; + } + + if (bbclk.fmt) { + printf("ds1302: Clock was in 12 hour mode, fixing\n"); + bbclk.fmt=0; + mod=1; + } + + if (bbclk.year>9) { + printf("ds1302: Year was corrupted, fixing\n"); + bbclk.year10=100; /* 2000 - why not? ;) */ + bbclk.year=0; + mod=1; + } + + /* Write out the changes if needed */ + if (mod) { + /* enable write protect */ + bbclk.WP = 1; + write_ser_drv(0xbe,(unsigned char *)&bbclk,8); + } else { + /* Else just turn write protect on */ + b = 0x80; + write_ser_drv(0x8e,&b,1); + } + DPRINTF("init done\n"); + + ds1302_initted=1; +} + +void +rtc_reset(void) +{ + if(!ds1302_initted) rtc_init(); + /* TODO */ +} + +void +rtc_get(struct rtc_time *tmp) +{ + struct ds1302_st bbclk; + + if(!ds1302_initted) rtc_init(); + + read_ser_drv(0xbe,(unsigned char *)&bbclk, 8); /* read burst */ + + if (bbclk.CH) { + printf("ds1302: rtc_get: Clock was halted, clock probably " + "corrupt\n"); + } + + tmp->tm_sec=10*bbclk.sec10+bbclk.sec; + tmp->tm_min=10*bbclk.min10+bbclk.min; + tmp->tm_hour=10*bbclk.hr10+bbclk.hr; + tmp->tm_wday=bbclk.day; + tmp->tm_mday=10*bbclk.date10+bbclk.date; + tmp->tm_mon=10*bbclk.month10+bbclk.month; + tmp->tm_year=10*bbclk.year10+bbclk.year + 1900; + + tmp->tm_yday = 0; + tmp->tm_isdst= 0; + + DPRINTF("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 ); +} + +void +rtc_set(struct rtc_time *tmp) +{ + struct ds1302_st bbclk; + unsigned char b=0; + + if(!ds1302_initted) rtc_init(); + + DPRINTF("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); + + memset(&bbclk,0,sizeof(bbclk)); + bbclk.CH=0; /* dont halt */ + bbclk.WP=1; /* write protect when we're done */ + + bbclk.sec10=tmp->tm_sec/10; + bbclk.sec=tmp->tm_sec%10; + + bbclk.min10=tmp->tm_min/10; + bbclk.min=tmp->tm_min%10; + + bbclk.hr10=tmp->tm_hour/10; + bbclk.hr=tmp->tm_hour%10; + + bbclk.day=tmp->tm_wday; + + bbclk.date10=tmp->tm_mday/10; + bbclk.date=tmp->tm_mday%10; + + bbclk.month10=tmp->tm_mon/10; + bbclk.month=tmp->tm_mon%10; + + tmp->tm_year -= 1900; + bbclk.year10=tmp->tm_year/10; + bbclk.year=tmp->tm_year%10; + + write_ser_drv(0x8e,&b,1); /* disable write protect */ + write_ser_drv(0xbe,(unsigned char *)&bbclk, 8); /* write burst */ +} + +#endif diff --git a/rtc/pcf8563.c b/rtc/pcf8563.c new file mode 100644 index 0000000..97b09b8 --- /dev/null +++ b/rtc/pcf8563.c @@ -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 + */ + +/* + * Date & Time support for Philips PCF8563 RTC + */ + +/* #define DEBUG */ + +#include <common.h> +#include <command.h> +#include <rtc.h> +#include <i2c.h> + +#if defined(CONFIG_RTC_PCF8563) && (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); + +/* ------------------------------------------------------------------------- */ + +void rtc_get (struct rtc_time *tmp) +{ + uchar sec, min, hour, mday, wday, mon_cent, year; + + sec = rtc_read (0x02); + min = rtc_read (0x03); + hour = rtc_read (0x04); + mday = rtc_read (0x05); + wday = rtc_read (0x06); + mon_cent= rtc_read (0x07); + year = rtc_read (0x08); + + debug ( "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 ); + debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n", + rtc_read (0x0C), + rtc_read (0x0B), + rtc_read (0x0A), + rtc_read (0x09) ); + + if (sec & 0x80) { + printf ("### Warning: RTC Low Voltage - date/time not reliable\n"); + } + + 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_cent & 0x1F); + tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900); + tmp->tm_wday = bcd2bin (wday & 0x07); + tmp->tm_yday = 0; + tmp->tm_isdst= 0; + + debug ( "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); +} + +void rtc_set (struct rtc_time *tmp) +{ + uchar century; + + debug ( "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); + + rtc_write (0x08, bin2bcd(tmp->tm_year % 100)); + + century = (tmp->tm_year >= 2000) ? 0x80 : 0; + rtc_write (0x07, bin2bcd(tmp->tm_mon) | century); + + rtc_write (0x06, bin2bcd(tmp->tm_wday)); + rtc_write (0x05, bin2bcd(tmp->tm_mday)); + rtc_write (0x04, bin2bcd(tmp->tm_hour)); + rtc_write (0x03, bin2bcd(tmp->tm_min )); + rtc_write (0x02, bin2bcd(tmp->tm_sec )); +} + +void rtc_reset (void) +{ + /* clear all control & status registers */ + rtc_write (0x00, 0x00); + rtc_write (0x01, 0x00); + rtc_write (0x0D, 0x00); + + /* clear Voltage Low bit */ + rtc_write (0x02, rtc_read (0x02) & 0x7F); + + /* reset all alarms */ + rtc_write (0x09, 0x00); + rtc_write (0x0A, 0x00); + rtc_write (0x0B, 0x00); + rtc_write (0x0C, 0x00); +} + +/* ------------------------------------------------------------------------- */ + +static uchar rtc_read (uchar reg) +{ + return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg)); +} + +static void rtc_write (uchar reg, uchar val) +{ + i2c_reg_write (CFG_I2C_RTC_ADDR, reg, 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_PCF8563 && CFG_CMD_DATE */ diff --git a/tools/bddb/README b/tools/bddb/README new file mode 100644 index 0000000..778e41c --- /dev/null +++ b/tools/bddb/README @@ -0,0 +1,116 @@ +Hymod Board Database + +(C) Copyright 2001 +Murray Jensen <Murray.Jensen@cmst.csiro.au> +CSIRO Manufacturing Science and Technology, Preston Lab + +25-Jun-01 + +This stuff is a set of PHP/MySQL scripts to implement a custom board +database. It will need *extensive* hacking to modify it to keep the +information about your custom boards that you want, however it is a good +starting point. + +How it is used: + + 1. a board has gone through all the hardware testing etc and is + ready to have the flash programmed for the first time - first you + go to a web page and fill in information about the board in a form + to register it in a database + + 2. the web stuff allocates a (unique) serial number and (optionally) + a (locally administered) ethernet address and stores the information + in a database using the serial number as the key (can do whole + batches of boards in one go and/or use a previously registered board + as defaults for the new board(s)) + + 3. it then creates a file in the tftp area of a server somewhere + containing the board information in a simple text format (one + per serial number) + + 4. all hymod boards have an i2c eeprom, and when U-Boot sees that + the eeprom is unitialised, it prompts for a serial number and + ethernet address (if not set), then transfers the file created + in step 3 from the server and initialises the eeprom from its + contents + +What this means is you can't boot the board until you have allocated a serial +number, but you don't have to type it all twice - you do it once on the web +and the board then finds the info it needs to initialise its eeprom. The +other side of the coin is the reading of the eeprom and how it gets passed +to Linux (or another O/S). + +To see how this is all done for the hymod boards look at the code in the +"board/hymod" directory and in the file "include/asm/hymod.h". Hymod boards +can have a mezzanine card which also have an eeprom that needs allocating, +the same process is used for these as well - just a different i2c address. + +Other forms provide the following functions: + + - browsing the board database + - editing board information (one at a time) + - maintaining/browsing a (simple) per board event log + +You will need: MySQL (I use version 3.23.7-alpha), PHP4 (with MySQL +support enabled) and a web server (I use Apache 1.3.x). + +I originally started by using phpMyBuilder (http://kyber.dk/phpMyBuilder) +but it soon got far more complicated than that could handle (but I left +the copyright messages in there anyway). Most of the code resides in the +common defs.php file, which shouldn't need much alteration - all the work +will be in shaping the front-end php files to your liking. + +Here's a quick summary of what needs doing to use it for your boards: + +1. get phpMyAdmin (http://phpwizard.net/projects/phpMyAdmin/) - it's an + invaluable tool for this sort of stuff (this step is optional of course) + +2. edit "bddb.css" to your taste, if you could be bothered - I have no + idea what is in there or what it does - I copied it from somewhere else + ("user.css" from the phpMyEdit (http://phpmyedit.sourcerforge.net) package, + I think) - I figure one day I'll see what sort of things I can change + in there. + +3. create a mysql database - call it whatever you like + +4. edit "create_tables.sql" and modify the "boards" table schema to + reflect the information you want to keep about your boards. It may or + may not be easier to do this and the next step in phpMyAdmin. Check out + the MySQL documentation at http://www.mysql.com/doc/ in particular the + column types at http://www.mysql.com/doc/C/o/Column_types.html - Note + there is only support for a few data types: + + int - presented as an html text input + char/text - presented as an html text input + date - presented as an html text input + enum - presented as an html radio input + + I also have what I call "enum_multi" which is a set of enums with the + same name, but suffixed with a number e.g. fred0, fred1, fred2. These + are presented as a number of html select's with a single label "fred" + this is useful for board characteristics that have multiple items of + the same type e.g. multiple banks of sdram. + +5. use the "create_tables.sql" file to create the "boards" table in the + database e.g. mysql dbname < create_tables.sql + +6. create a user and password for the web server to log into the MySQL + database with; give this user select, insert and update privileges + to the database created in 3 (and delete, if you want the "delete" + functions in the edit forms to work- I have this turned off). phpMyAdmin + helps in this step. + +7. edit "config.php" and set the variables: $mysql_user, $mysql_pw, $mysql_db, + $bddb_cfgdir and $bddb_label - keep the contents of this file secret - it + contains the web servers username and password (the three $mysql_* vars + are set from the previous step) + +8. edit "defs.php" and a. adjust the various enum value arrays and b. edit + the function "pg_foot()" to remove my email address :-) + +9. do major hacking on the following files: browse.php, doedit.php, donew.php, + edit.php and new.php to reflect your database schema - fortunately the + hacking is fairly straight-forward, but it is boring and time-consuming. + +These notes were written rather hastily - if you find any obvious problems +please let me know. diff --git a/tools/bddb/brlog.php b/tools/bddb/brlog.php new file mode 100644 index 0000000..6e98c9c --- /dev/null +++ b/tools/bddb/brlog.php @@ -0,0 +1,106 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // list page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Browse Board Log"); + + if (!isset($serno) || $serno == 0) + die("serial number not specified!"); + + function print_cell($str) { + if ($str == '') + $str = ' '; + echo "\t<td>$str</td>\n"; + } +?> +<table align=center border=1 cellpadding=10> +<tr> +<th>serno / edit</th> +<th>ethaddr</th> +<th>date</th> +<th>batch</th> +<th>type</th> +<th>rev</th> +<th>location</th> +</tr> +<?php + $r=mysql_query("select * from boards where serno=$serno"); + + while($row=mysql_fetch_array($r)){ + foreach ($columns as $key) { + if (!key_in_array($key, $row)) + $row[$key] = ''; + } + + echo "<tr>\n"; + print_cell("<a href=\"edit.php?serno=$row[serno]\">$row[serno]</a>"); + print_cell($row['ethaddr']); + print_cell($row['date']); + print_cell($row['batch']); + print_cell($row['type']); + print_cell($row['rev']); + print_cell($row['location']); + echo "</tr>\n"; + } + + mysql_free_result($r); +?> +</table> +<hr></hr> +<p></p> +<?php + $limit=abs(isset($limit)?$limit:20); + $offset=abs(isset($offset)?$offset:0); + $lr=mysql_query("select count(*) as n from log where serno=$serno"); + $lrow=mysql_fetch_array($lr); + if($lrow['n']>$limit){ + $preoffset=max(0,$offset-$limit); + $postoffset=$offset+$limit; + echo "<table width=\"100%\">\n<tr align=center>\n"; + printf("<td><%sa href=\"%s?serno=$serno&offset=%d\"><img border=0 alt=\"<\" src=\"/icons/left.gif\"></a></td>\n", $offset>0?"":"no", $PHP_SELF, $preoffset); + printf("<td><%sa href=\"%s?serno=$serno&offset=%d\"><img border=0 alt=\">\" src=\"/icons/right.gif\"></a></td>\n", $postoffset<$lrow['n']?"":"no", $PHP_SELF, $postoffset); + echo "</tr>\n</table>\n"; + } + mysql_free_result($lr); +?> +<table width="100%" border=1 cellpadding=10> +<tr valign=top> +<th>logno / edit</th> +<th>date</th> +<th width="70%">details</th> +</tr> +<?php + $r=mysql_query("select * from log where serno=$serno order by logno limit $offset,$limit"); + + while($row=mysql_fetch_array($r)){ + echo "<tr>\n"; + print_cell("<a href=\"edlog.php?serno=$row[serno]&logno=$row[logno]\">$row[logno]</a>"); + print_cell($row['date']); + print_cell("<pre>" . urldecode($row['details']) . "</pre>"); + echo "</tr>\n"; + } + + mysql_free_result($r); +?> +</table> +<hr></hr> +<p></p> +<table width="100%"> +<tr> + <td align=center> + <a href="newlog.php?serno=<?php echo "$serno"; ?>">Add to Log</a> + </td> + <td align=center> + <a href="index.php">Back to Start</a> + </td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/browse.php b/tools/bddb/browse.php new file mode 100644 index 0000000..b7cd508 --- /dev/null +++ b/tools/bddb/browse.php @@ -0,0 +1,130 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // list page (hymod_bddb / boards) + + require("defs.php"); + + if (!isset($verbose)) + $verbose = 0; + + if (!isset($serno)) + $serno = 0; + + pg_head("$bddb_label - Browse database" . ($verbose?" (verbose)":"")); +?> +<p></p> +<?php + if ($serno == 0) { + $limit=abs(isset($limit)?$limit:20); + $offset=abs(isset($offset)?$offset:0); + $lr=mysql_query("select count(*) as n from boards"); + $lrow=mysql_fetch_array($lr); + if($lrow['n']>$limit){ + $preoffset=max(0,$offset-$limit); + $postoffset=$offset+$limit; + echo "<table width=\"100%\">\n<tr align=center>\n"; + printf("<td><%sa href=\"%s?offset=%d\"><img border=0 alt=\"<\" src=\"/icons/left.gif\"></a></td>\n", $offset>0?"":"no", $PHP_SELF, $preoffset); + printf("<td><%sa href=\"%s?offset=%d\"><img border=0 alt=\">\" src=\"/icons/right.gif\"></a></td>\n", $postoffset<$lrow['n']?"":"no", $PHP_SELF, $postoffset); + echo "</tr>\n</table>\n"; + } + mysql_free_result($lr); + } +?> +<table align=center border=1 cellpadding=10> +<tr> +<th></th> +<th>serno / edit</th> +<th>ethaddr</th> +<th>date</th> +<th>batch</th> +<th>type</th> +<th>rev</th> +<th>location</th> +<?php + if ($verbose) { + echo "<th>comments</th>\n"; + echo "<th>sdram</th>\n"; + echo "<th>flash</th>\n"; + echo "<th>zbt</th>\n"; + echo "<th>xlxtyp</th>\n"; + echo "<th>xlxspd</th>\n"; + echo "<th>xlxtmp</th>\n"; + echo "<th>xlxgrd</th>\n"; + echo "<th>cputyp</th>\n"; + echo "<th>cpuspd</th>\n"; + echo "<th>cpmspd</th>\n"; + echo "<th>busspd</th>\n"; + echo "<th>hstype</th>\n"; + echo "<th>hschin</th>\n"; + echo "<th>hschout</th>\n"; + } +?> +</tr> +<?php + if ($serno == 0) + $r=mysql_query("select * from boards order by serno limit $offset,$limit"); + else + $r=mysql_query("select * from boards where serno=$serno"); + + function print_cell($str) { + if ($str == '') + $str = ' '; + echo "\t<td>$str</td>\n"; + } + + while($row=mysql_fetch_array($r)){ + foreach ($columns as $key) { + if (!key_in_array($key, $row)) + $row[$key] = ''; + } + + echo "<tr>\n"; + print_cell("<a href=\"brlog.php?serno=$row[serno]\">Log</a>"); + print_cell("<a href=\"edit.php?serno=$row[serno]\">$row[serno]</a>"); + print_cell($row['ethaddr']); + print_cell($row['date']); + print_cell($row['batch']); + print_cell($row['type']); + print_cell($row['rev']); + print_cell($row['location']); + if ($verbose) { + print_cell("<pre>\n" . urldecode($row['comments']) . + "\n\t</pre>"); + print_cell(gather_enum_multi_print("sdram", 4, $row)); + print_cell(gather_enum_multi_print("flash", 4, $row)); + print_cell(gather_enum_multi_print("zbt", 16, $row)); + print_cell(gather_enum_multi_print("xlxtyp", 4, $row)); + print_cell(gather_enum_multi_print("xlxspd", 4, $row)); + print_cell(gather_enum_multi_print("xlxtmp", 4, $row)); + print_cell(gather_enum_multi_print("xlxgrd", 4, $row)); + print_cell($row['cputyp']); + print_cell($row['cpuspd']); + print_cell($row['cpmspd']); + print_cell($row['busspd']); + print_cell($row['hstype']); + print_cell($row['hschin']); + print_cell($row['hschout']); + } + echo "</tr>\n"; + } +?> +</table> +<p></p> +<table width="100%"> +<tr> + <td align=center><?php + if ($verbose) + echo "<a href=\"browse.php?verbose=0\">Terse Listing</a>"; + else + echo "<a href=\"browse.php?verbose=1\">Verbose Listing</a>"; + ?></td> + <td align=center><a href="index.php">Back to Start</a></td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/config.php b/tools/bddb/config.php new file mode 100644 index 0000000..8d54993 --- /dev/null +++ b/tools/bddb/config.php @@ -0,0 +1,16 @@ +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // mysql database access info + $mysql_user="fred"; + $mysql_pw="apassword"; + $mysql_db="mydbname"; + + // where to put the eeprom config files + $bddb_cfgdir = '/tftpboot/bddb'; + + // what this database is called + $bddb_label = 'Hymod Board Database'; +?> diff --git a/tools/bddb/create_tables.sql b/tools/bddb/create_tables.sql new file mode 100644 index 0000000..aa007c1 --- /dev/null +++ b/tools/bddb/create_tables.sql @@ -0,0 +1,90 @@ +# phpMyAdmin MySQL-Dump +# http://phpwizard.net/phpMyAdmin/ +# +# Host: localhost Database : hymod_bddb + +# (C) Copyright 2001 +# Murray Jensen <Murray.Jensen@cmst.csiro.au> +# CSIRO Manufacturing Science and Technology, Preston Lab + +# -------------------------------------------------------- +# +# Table structure for table 'boards' +# + +DROP TABLE IF EXISTS boards; +CREATE TABLE boards ( + serno int(10) unsigned zerofill NOT NULL auto_increment, + ethaddr char(17), + date date NOT NULL, + batch char(32), + type enum('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY') NOT NULL, + rev tinyint(3) unsigned zerofill NOT NULL, + location char(64), + comments text, + sdram0 enum('32M','64M','128M','256M'), + sdram1 enum('32M','64M','128M','256M'), + sdram2 enum('32M','64M','128M','256M'), + sdram3 enum('32M','64M','128M','256M'), + flash0 enum('4M','8M','16M','32M','64M'), + flash1 enum('4M','8M','16M','32M','64M'), + flash2 enum('4M','8M','16M','32M','64M'), + flash3 enum('4M','8M','16M','32M','64M'), + zbt0 enum('512K','1M','2M','4M'), + zbt1 enum('512K','1M','2M','4M'), + zbt2 enum('512K','1M','2M','4M'), + zbt3 enum('512K','1M','2M','4M'), + zbt4 enum('512K','1M','2M','4M'), + zbt5 enum('512K','1M','2M','4M'), + zbt6 enum('512K','1M','2M','4M'), + zbt7 enum('512K','1M','2M','4M'), + zbt8 enum('512K','1M','2M','4M'), + zbt9 enum('512K','1M','2M','4M'), + zbta enum('512K','1M','2M','4M'), + zbtb enum('512K','1M','2M','4M'), + zbtc enum('512K','1M','2M','4M'), + zbtd enum('512K','1M','2M','4M'), + zbte enum('512K','1M','2M','4M'), + zbtf enum('512K','1M','2M','4M'), + xlxtyp0 enum('XCV300E','XCV400E','XCV600E'), + xlxtyp1 enum('XCV300E','XCV400E','XCV600E'), + xlxtyp2 enum('XCV300E','XCV400E','XCV600E'), + xlxtyp3 enum('XCV300E','XCV400E','XCV600E'), + xlxspd0 enum('6','7','8'), + xlxspd1 enum('6','7','8'), + xlxspd2 enum('6','7','8'), + xlxspd3 enum('6','7','8'), + xlxtmp0 enum('COM','IND'), + xlxtmp1 enum('COM','IND'), + xlxtmp2 enum('COM','IND'), + xlxtmp3 enum('COM','IND'), + xlxgrd0 enum('NORMAL','ENGSAMP'), + xlxgrd1 enum('NORMAL','ENGSAMP'), + xlxgrd2 enum('NORMAL','ENGSAMP'), + xlxgrd3 enum('NORMAL','ENGSAMP'), + cputyp enum('MPC8260'), + cpuspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ'), + cpmspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ'), + busspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ'), + hstype enum('AMCC-S2064A'), + hschin enum('0','1','2','3','4'), + hschout enum('0','1','2','3','4'), + PRIMARY KEY (serno), + KEY serno (serno), + UNIQUE serno_2 (serno) +); + +# +# Table structure for table 'log' +# + +DROP TABLE IF EXISTS log; +CREATE TABLE log ( + logno int(10) unsigned zerofill NOT NULL auto_increment, + serno int(10) unsigned zerofill NOT NULL, + date date NOT NULL, + details text NOT NULL, + PRIMARY KEY (logno), + KEY logno (logno, serno, date), + UNIQUE logno_2 (logno) +); diff --git a/tools/bddb/defs.php b/tools/bddb/defs.php new file mode 100644 index 0000000..0393dbd --- /dev/null +++ b/tools/bddb/defs.php @@ -0,0 +1,663 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // contains mysql user id and password - keep secret + require("config.php"); + + if (isset($logout)) { + Header("status: 401 Unauthorized"); + Header("HTTP/1.0 401 Unauthorized"); + Header("WWW-authenticate: basic realm=\"$bddb_label\""); + + echo "<html><head><title>" . + "Access to '$bddb_label' Denied" . + "</title></head>\n"; + echo "<body bgcolor=#ffffff><br></br><br></br><center><h1>" . + "You must be an Authorised User " . + "to access the '$bddb_label'" . + "</h1>\n</center></body></html>\n"; + exit; + } + + // contents of the various enumerated types - if first item is + // empty ('') then the enum is allowed to be null (ie "not null" + // is not set on the column) + + // all column names in the database table + $columns = array( + 'serno','ethaddr','date','batch', + 'type','rev','location','comments', + 'sdram0','sdram1','sdram2','sdram3', + 'flash0','flash1','flash2','flash3', + 'zbt0','zbt1','zbt2','zbt3','zbt4','zbt5','zbt6','zbt7', + 'zbt8','zbt9','zbta','zbtb','zbtc','zbtd','zbte','zbtf', + 'xlxtyp0','xlxtyp1','xlxtyp2','xlxtyp3', + 'xlxspd0','xlxspd1','xlxspd2','xlxspd3', + 'xlxtmp0','xlxtmp1','xlxtmp2','xlxtmp3', + 'xlxgrd0','xlxgrd1','xlxgrd2','xlxgrd3', + 'cputyp','cpuspd','cpmspd','busspd', + 'hstype','hschin','hschout' + ); + + // board type + $type_vals = array('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY'); + + // sdram sizes (nbits array is for write into eeprom config file) + $sdram_vals = array('','32M','64M','128M','256M'); + $sdram_nbits = array(0,25,26,27,28); + + // flash sizes (nbits array is for write into eeprom config file) + $flash_vals = array('','4M','8M','16M','32M','64M'); + $flash_nbits = array(0,22,23,24,25,26); + + // zbt ram sizes (nbits array is for write into eeprom config file) + $zbt_vals = array('','512K','1M','2M','4M'); + $zbt_nbits = array(0,19,20,21,22); + + // Xilinx attributes + $xlxtyp_vals = array('','XCV300E','XCV400E','XCV600E'); + $xlxspd_vals = array('','6','7','8'); + $xlxtmp_vals = array('','COM','IND'); + $xlxgrd_vals = array('','NORMAL','ENGSAMP'); + + // processor attributes + $cputyp_vals = array('','MPC8260'); + $clk_vals = array('','33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ'); + + // high-speed serial attributes + $hstype_vals = array('','AMCC-S2064A'); + $hschin_vals = array('0','1','2','3','4'); + $hschout_vals = array('0','1','2','3','4'); + + // value filters - used when outputting html + function rev_filter($num) { + if ($num == 0) + return "001"; + else + return sprintf("%03d", $num); + } + + function text_filter($str) { + return urldecode($str); + } + + mt_srand(time() | getmypid()); + + // set up MySQL connection + mysql_connect("", $mysql_user, $mysql_pw) || die("cannot connect"); + mysql_select_db($mysql_db) || die("cannot select db"); + + // page header + function pg_head($title) + { + echo "<html>\n<head>\n"; + echo "<link rel=stylesheet href=\"bddb.css\" type=\"text/css\" title=\"style sheet\"></link>\n"; + echo "<title>$title</title>\n"; + echo "</head>\n"; + echo "<body>\n"; + echo "<center><h1>$title</h1></center>\n"; + echo "<hr></hr>\n"; + } + + // page footer + function pg_foot() + { + echo "<hr></hr>\n"; + echo "<table width=\"100%\"><tr><td align=left>\n<address>" . + "If you have any problems, email " . + "<a href=\"mailto:Murray.Jensen@cmst.csiro.au\">" . + "Murray Jensen" . + "</a></address>\n" . + "</td><td align=right>\n" . + "<a href=\"index.php?logout=true\">logout</a>\n" . + "</td></tr></table>\n"; + echo "<p><small><i>Made with " . + "<a href=\"http://kyber.dk/phpMyBuilder/\">" . + "Kyber phpMyBuilder</a></i></small></p>\n"; + echo "</body>\n"; + echo "</html>\n"; + } + + // some support functions + + if (!function_exists('array_search')) { + + function array_search($needle, $haystack, $strict = false) { + + if (is_array($haystack) && count($haystack)) { + + $ntype = gettype($needle); + + foreach ($haystack as $key => $value) { + + if ($value == $needle && (!$strict || + gettype($value) == $ntype)) + return $key; + } + } + + return false; + } + } + + if (!function_exists('in_array')) { + + function in_array($needle, $haystack, $strict = false) { + + if (is_array($haystack) && count($haystack)) { + + $ntype = gettype($needle); + + foreach ($haystack as $key => $value) { + + if ($value == $needle && (!$strict || + gettype($value) == $ntype)) + return true; + } + } + + return false; + } + } + + function key_in_array($key, $array) { + return in_array($key, array_keys($array), true); + } + + function enum_to_index($name, $vals) { + $index = array_search($GLOBALS[$name], $vals); + if ($vals[0] != '') + $index++; + return $index; + } + + // fetch a value from an array - return empty string is not present + function get_key_value($key, $array) { + if (key_in_array($key, $array)) + return $array[$key]; + else + return ''; + } + + function fprintf() { + $n = func_num_args(); + if ($n < 2) + return FALSE; + $a = func_get_args(); + $fp = array_shift($a); + $x = "\$s = sprintf"; + $sep = '('; + foreach ($a as $z) { + $x .= "$sep'$z'"; + $sep = ','; + } + $x .= ');'; + eval($x); + $l = strlen($s); + $r = fwrite($fp, $s, $l); + if ($r != $l) + return FALSE; + else + return TRUE; + } + + // functions to display (print) a database table and its columns + + function begin_table($ncols) { + global $table_ncols; + $table_ncols = $ncols; + echo "<table align=center width=\"100%\"" + . " border=1 cellpadding=4 cols=$table_ncols>\n"; + } + + function begin_field($name, $span = 0) { + global $table_ncols; + echo "<tr valign=top>\n"; + echo "\t<th align=center>$name</th>\n"; + if ($span <= 0) + $span = $table_ncols - 1; + if ($span > 1) + echo "\t<td colspan=$span>\n"; + else + echo "\t<td>\n"; + } + + function cont_field($span = 1) { + echo "\t</td>\n"; + if ($span > 1) + echo "\t<td colspan=$span>\n"; + else + echo "\t<td>\n"; + } + + function end_field() { + echo "\t</td>\n"; + echo "</tr>\n"; + } + + function end_table() { + echo "</table>\n"; + } + + function print_field($name, $array, $size = 0, $filt='') { + + begin_field($name); + + if (key_in_array($name, $array)) + $value = $array[$name]; + else + $value = ''; + + if ($filt != '') + $value = $filt($value); + + echo "\t\t<input name=$name value=\"$value\""; + if ($size > 0) + echo " size=$size maxlength=$size"; + echo "></input>\n"; + + end_field(); + } + + function print_field_multiline($name, $array, $cols, $rows, $filt='') { + + begin_field($name); + + if (key_in_array($name, $array)) + $value = $array[$name]; + else + $value = ''; + + if ($filt != '') + $value = $filt($value); + + echo "\t\t<textarea name=$name " . + "cols=$cols rows=$rows wrap=off>\n"; + echo "$value"; + echo "</textarea>\n"; + + end_field(); + } + + // print a mysql ENUM as an html RADIO INPUT + function print_enum($name, $array, $vals, $def = -1) { + + begin_field($name); + + if (key_in_array($name, $array)) + $chk = array_search($array[$name], $vals, FALSE); + else + $chk = $def; + + $nval = count($vals); + + for ($i = 0; $i < $nval; $i++) { + + $val = $vals[$i]; + if ($val == '') + $pval = "none"; + else + $pval = "$val"; + + printf("\t\t<input type=radio name=$name" + . " value=\"$val\"%s>$pval</input>\n", + $i == $chk ? " checked" : ""); + } + + end_field(); + } + + // print a group of mysql ENUMs (e.g. name0,name1,...) as an html SELECT + function print_enum_multi($base, $array, $vals, $cnt, $defs, $grp = 0) { + + global $table_ncols; + + if ($grp <= 0) + $grp = $cnt; + $ncell = $cnt / $grp; + $span = ($table_ncols - 1) / $ncell; + + begin_field($base, $span); + + $nval = count($vals); + + for ($i = 0; $i < $cnt; $i++) { + + if ($i > 0 && ($i % $grp) == 0) + cont_field($span); + + $name = sprintf("%s%x", $base, $i); + + echo "\t\t<select name=$name>\n"; + + if (key_in_array($name, $array)) + $ai = array_search($array[$name], $vals, FALSE); + else { + if (key_in_array($i, $defs)) + $ai = $defs[$i]; + else + $ai = 0; + } + + for ($j = 0; $j < $nval; $j++) { + + $val = $vals[$j]; + if ($val == '') + $pval = " "; + else + $pval = "$val"; + + printf("\t\t\t<option " . + "value=\"%s\"%s>%s</option>\n", + $val, + $j == $ai ? " selected" : "", + $pval); + } + + echo "\t\t</select>\n"; + } + + end_field(); + } + + // functions to handle the form input + + // fetch all the parts of an "enum_multi" into a string suitable + // for a MySQL query + function gather_enum_multi_query($base, $cnt) { + + $retval = ''; + + for ($i = 0; $i < $cnt; $i++) { + + $name = sprintf("%s%x", $base, $i); + + if (isset($GLOBALS[$name])) { + $retval .= sprintf(", %s='%s'", + $name, $GLOBALS[$name]); + } + } + + return $retval; + } + + // fetch all the parts of an "enum_multi" into a string suitable + // for a display e.g. in an html table cell + function gather_enum_multi_print($base, $cnt, $array) { + + $retval = ''; + + for ($i = 0; $i < $cnt; $i++) { + + $name = sprintf("%s%x", $base, $i); + + if ($array[$name] != '') { + if ($retval != '') + $retval .= ','; + $retval .= $array[$name]; + } + } + + return $retval; + } + + // fetch all the parts of an "enum_multi" into a string suitable + // for writing to the eeprom data file + function gather_enum_multi_write($base, $cnt, $vals, $xfrm = array()) { + + $retval = ''; + + for ($i = 0; $i < $cnt; $i++) { + + $name = sprintf("%s%x", $base, $i); + + if ($GLOBALS[$name] != '') { + if ($retval != '') + $retval .= ','; + $index = enum_to_index($name, $vals); + if ($xfrm != array()) + $retval .= $xfrm[$index]; + else + $retval .= $index; + } + } + + return $retval; + } + + // count how many parts of an "enum_multi" are actually set + function count_enum_multi($base, $cnt) { + + $retval = 0; + + for ($i = 0; $i < $cnt; $i++) { + + $name = sprintf("%s%x", $base, $i); + + if (isset($GLOBALS[$name])) + $retval++; + } + + return $retval; + } + + // ethernet address functions + + // generate a (possibly not unique) random vendor ethernet address + // (setting bit 6 in the ethernet address - motorola wise i.e. bit 0 + // is the most significant bit - means it is not an assigned ethernet + // address). Also, make sure it is NOT a multicast ethernet address. + function gen_eth_addr($serno) { + + $ethaddr_high = (mt_rand(0, 65535) & 0xfeff) | 0x0200; + $ethaddr_low = mt_rand(0, 4294967295); + + return sprintf("%02lx:%02lx:%02lx:%02lx:%02lx:%02lx", + $ethaddr_high >> 8, $ethaddr_high & 0xff, + $ethaddr_low >> 24, ($ethaddr_low >> 16) & 0xff, + ($ethaddr_low >> 8) & 0xff, $ethaddr_low & 0xff); + } + + // check that an ethernet address is valid + function eth_addr_is_valid($ethaddr) { + + $ethbytes = split(':', $ethaddr); + + if (count($ethbytes) != 6) + return FALSE; + + for ($i = 0; $i < 6; $i++) { + $ethbyte = $ethbytes[$i]; + if (!ereg('^[0-9a-f][0-9a-f]$', $ethbyte)) + return FALSE; + } + + return TRUE; + } + + // write a simple eeprom configuration file + function write_eeprom_cfg_file() { + + global $sernos, $nsernos, $bddb_cfgdir, $numerrs, $cfgerrs; + global $date, $batch, $type_vals, $rev; + global $sdram_vals, $sdram_nbits; + global $flash_vals, $flash_nbits; + global $zbt_vals, $zbt_nbits; + global $xlxtyp_vals, $xlxspd_vals, $xlxtmp_vals, $xlxgrd_vals; + global $cputyp, $cputyp_vals, $clk_vals; + global $hstype, $hstype_vals, $hschin, $hschout; + + $numerrs = 0; + $cfgerrs = array(); + + for ($i = 0; $i < $nsernos; $i++) { + + $serno = sprintf("%010d", $sernos[$i]); + + $wfp = @fopen($bddb_cfgdir . "/$serno.cfg", "w"); + if (!$wfp) { + $cfgerrs[$i] = 'file create fail'; + $numerrs++; + continue; + } + set_file_buffer($wfp, 0); + + if (!fprintf($wfp, "serno=%d\n", $sernos[$i])) { + $cfgerrs[$i] = 'cfg wr fail (serno)'; + fclose($wfp); + $numerrs++; + continue; + } + + if (!fprintf($wfp, "date=%s\n", $date)) { + $cfgerrs[$i] = 'cfg wr fail (date)'; + fclose($wfp); + $numerrs++; + continue; + } + + if ($batch != '') { + if (!fprintf($wfp, "batch=%s\n", $batch)) { + $cfgerrs[$i] = 'cfg wr fail (batch)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $typei = enum_to_index("type", $type_vals); + if (!fprintf($wfp, "type=%d\n", $typei)) { + $cfgerrs[$i] = 'cfg wr fail (type)'; + fclose($wfp); + $numerrs++; + continue; + } + + if (!fprintf($wfp, "rev=%d\n", $rev)) { + $cfgerrs[$i] = 'cfg wr fail (rev)'; + fclose($wfp); + $numerrs++; + continue; + } + + $s = gather_enum_multi_write("sdram", 4, + $sdram_vals, $sdram_nbits); + if ($s != '') { + $b = fprintf($wfp, "sdram=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (sdram)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $s = gather_enum_multi_write("flash", 4, + $flash_vals, $flash_nbits); + if ($s != '') { + $b = fprintf($wfp, "flash=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (flash)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $s = gather_enum_multi_write("zbt", 16, + $zbt_vals, $zbt_nbits); + if ($s != '') { + $b = fprintf($wfp, "zbt=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (zbt)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $s = gather_enum_multi_write("xlxtyp", 4, $xlxtyp_vals); + if ($s != '') { + $b = fprintf($wfp, "xlxtyp=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (xlxtyp)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $s = gather_enum_multi_write("xlxspd", 4, $xlxspd_vals); + if ($s != '') { + $b = fprintf($wfp, "xlxspd=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (xlxspd)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $s = gather_enum_multi_write("xlxtmp", 4, $xlxtmp_vals); + if ($s != '') { + $b = fprintf($wfp, "xlxtmp=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (xlxtmp)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + $s = gather_enum_multi_write("xlxgrd", 4, $xlxgrd_vals); + if ($s != '') { + $b = fprintf($wfp, "xlxgrd=%s\n", $s); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (xlxgrd)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + if ($cputyp != '') { + $cputypi = enum_to_index("cputyp",$cputyp_vals); + $cpuspdi = enum_to_index("cpuspd", $clk_vals); + $busspdi = enum_to_index("busspd", $clk_vals); + $cpmspdi = enum_to_index("cpmspd", $clk_vals); + $b = fprintf($wfp, "cputyp=%d\ncpuspd=%d\n" . + "busspd=%d\ncpmspd=%d\n", + $cputypi, $cpuspdi, $busspdi, $cpmspdi); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (cputyp)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + if ($hstype != '') { + $hstypei = enum_to_index("hstype",$hstype_vals); + $b = fprintf($wfp, "hstype=%d\n" . + "hschin=%s\nhschout=%s\n", + $hstypei, $hschin, $hschout); + if (!$b) { + $cfgerrs[$i] = 'cfg wr fail (hstype)'; + fclose($wfp); + $numerrs++; + continue; + } + } + + if (!fclose($wfp)) { + $cfgerrs[$i] = 'file cls fail'; + $numerrs++; + } + } + + return $numerrs; + } +?> diff --git a/tools/bddb/dodelete.php b/tools/bddb/dodelete.php new file mode 100644 index 0000000..839ad8c --- /dev/null +++ b/tools/bddb/dodelete.php @@ -0,0 +1,64 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // dodelete page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Delete Board Results"); + + if (!($serno=intval($serno))) + die("the board serial number was not specified"); + + mysql_query("delete from boards where serno=$serno"); + + if(mysql_errno()) { + $errstr = mysql_error(); + echo "\t<font size=+4>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe following error was encountered:\n"; + echo "\t\t</p>\n"; + echo "\t\t<center>\n"; + printf("\t\t\t<b>%s</b>\n", $errstr); + echo "\t\t</center>\n"; + echo "\t</font>\n"; + } + else { + echo "\t<font size=+2>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe board with serial number <b>$serno</b> was" + . " successfully deleted\n"; + mysql_query("delete from log where serno=$serno"); + if (mysql_errno()) { + $errstr = mysql_error(); + echo "\t\t\t<font size=+4>\n"; + echo "\t\t\t\t<p>\n"; + echo "\t\t\t\t\tBut the following error occurred " . + "when deleting the log entries:\n"; + echo "\t\t\t\t</p>\n"; + echo "\t\t\t\t<center>\n"; + printf("\t\t\t\t\t<b>%s</b>\n", $errstr); + echo "\t\t\t\t</center>\n"; + echo "\t\t\t</font>\n"; + } + echo "\t\t</p>\n"; + echo "\t</font>\n"; + } +?> +<p> +<table width="100%"> +<tr> + <td align=center> + <a href="browse.php">Back to Browse</a> + </td> + <td align=center> + <a href="index.php">Back to Start</a> + </td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/dodellog.php b/tools/bddb/dodellog.php new file mode 100644 index 0000000..d5822c5 --- /dev/null +++ b/tools/bddb/dodellog.php @@ -0,0 +1,55 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // dodelete page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Delete Log Entry Results"); + + if (!($serno=intval($serno))) + die("the board serial number was not specified"); + + if (!isset($logno) || $logno == 0) + die("the log entry number not specified!"); + + mysql_query("delete from log where serno=$serno and logno=$logno"); + + if(mysql_errno()) { + $errstr = mysql_error(); + echo "\t<font size=+4>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe following error was encountered:\n"; + echo "\t\t</p>\n"; + echo "\t\t<center>\n"; + printf("\t\t\t<b>%s</b>\n", $errstr); + echo "\t\t</center>\n"; + echo "\t</font>\n"; + } + else { + echo "\t<font size=+2>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe log entry with log number <b>$logno</b>\n"; + echo "\t\t\tand serial number <b>$serno</b> "; + echo "was successfully deleted\n"; + echo "\t\t</p>\n"; + echo "\t</font>\n"; + } +?> +<p> +<table width="100%"> +<tr> + <td align=center> + <a href="brlog.php?serno=<?php echo "$serno"; ?>">Back to Log</a> + </td> + <td align=center> + <a href="index.php">Back to Start</a> + </td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/doedit.php b/tools/bddb/doedit.php new file mode 100644 index 0000000..110ecf3 --- /dev/null +++ b/tools/bddb/doedit.php @@ -0,0 +1,170 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // doedit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Edit Board Results"); + + if ($serno == 0) + die("the board serial number was not specified"); + + $query="update boards set"; + + if (isset($ethaddr)) { + if (!eth_addr_is_valid($ethaddr)) + die("ethaddr is invalid ('$ethaddr')"); + $query.=" ethaddr='$ethaddr',"; + } + + if (isset($date)) { + list($y, $m, $d) = split("-", $date); + if (!checkdate($m, $d, $y) || $y < 1999) + die("date is invalid (input '$date', " . + "yyyy-mm-dd '$y-$m-$d')"); + $query.=" date='$date'"; + } + + if (isset($batch)) { + if (strlen($batch) > 32) + die("batch field too long (>32)"); + $query.=", batch='$batch'"; + } + + if (isset($type)) { + if (!in_array($type, $type_vals)) + die("Invalid type ($type) specified"); + $query.=", type='$type'"; + } + + if (isset($rev)) { + if (($rev = intval($rev)) <= 0 || $rev > 255) + die("Revision number is invalid ($rev)"); + $query.=sprintf(", rev=%d", $rev); + } + + if (isset($location)) { + if (strlen($location) > 64) + die("location field too long (>64)"); + $query.=", location='$location'"; + } + + if (isset($comments)) + $query.=", comments='" . rawurlencode($comments) . "'"; + + $query.=gather_enum_multi_query("sdram", 4); + + $query.=gather_enum_multi_query("flash", 4); + + $query.=gather_enum_multi_query("zbt", 16); + + $query.=gather_enum_multi_query("xlxtyp", 4); + $nxlx = count_enum_multi("xlxtyp", 4); + + $query.=gather_enum_multi_query("xlxspd", 4); + if (count_enum_multi("xlxspd", 4) != $nxlx) + die("number of xilinx speeds not same as number of types"); + + $query.=gather_enum_multi_query("xlxtmp", 4); + if (count_enum_multi("xlxtmp", 4) != $nxlx) + die("number of xilinx temps. not same as number of types"); + + $query.=gather_enum_multi_query("xlxgrd", 4); + if (count_enum_multi("xlxgrd", 4) != $nxlx) + die("number of xilinx grades not same as number of types"); + + if (isset($cputyp)) { + $query.=", cputyp='$cputyp'"; + if ($cpuspd == '') + die("must specify cpu speed if cpu type is defined"); + $query.=", cpuspd='$cpuspd'"; + if ($cpmspd == '') + die("must specify cpm speed if cpu type is defined"); + $query.=", cpmspd='$cpmspd'"; + if ($busspd == '') + die("must specify bus speed if cpu type is defined"); + $query.=", busspd='$busspd'"; + } + else { + if (isset($cpuspd)) + die("can't specify cpu speed if there is no cpu"); + if (isset($cpmspd)) + die("can't specify cpm speed if there is no cpu"); + if (isset($busspd)) + die("can't specify bus speed if there is no cpu"); + } + + if (isset($hschin)) { + if (($hschin = intval($hschin)) < 0 || $hschin > 4) + die("Invalid number of hs input chans ($hschin)"); + } + else + $hschin = 0; + if (isset($hschout)) { + if (($hschout = intval($hschout)) < 0 || $hschout > 4) + die("Invalid number of hs output chans ($hschout)"); + } + else + $hschout = 0; + if (isset($hstype)) + $query.=", hstype='$hstype'"; + else { + if ($hschin != 0) + die("number of high-speed input channels must be zero" + . " if high-speed chip is not present"); + if ($hschout != 0) + die("number of high-speed output channels must be zero" + . " if high-speed chip is not present"); + } + $query.=", hschin='$hschin'"; + $query.=", hschout='$hschout'"; + + $query.=" where serno=$serno"; + + mysql_query($query); + if(mysql_errno()) { + $errstr = mysql_error(); + echo "\t<font size=+4>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe following error was encountered:\n"; + echo "\t\t</p>\n"; + echo "\t\t<center>\n"; + printf("\t\t\t<b>%s</b>\n", $errstr); + echo "\t\t</center>\n"; + echo "\t</font>\n"; + } + else { + $sernos = array($serno); + $nsernos = 1; + + write_eeprom_cfg_file(); + + echo "\t<font size=+2>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe board with serial number <b>$serno</b> was" + . " successfully updated"; + if ($numerrs > 0) { + $errstr = $cfgerrs[0]; + echo "<br>\n\t\t\t"; + echo "(but the cfg file update failed: $errstr)"; + } + echo "\n"; + echo "\t\t</p>\n"; + echo "\t</font>\n"; + } + +?> +<p> +<table align=center width="100%"> +<tr> + <td align=center><a href="browse.php">Back to Browse</a></td> + <td align=center><a href="index.php">Back to Start</a></td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/doedlog.php b/tools/bddb/doedlog.php new file mode 100644 index 0000000..db27c37 --- /dev/null +++ b/tools/bddb/doedlog.php @@ -0,0 +1,66 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // doedit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Edit Log Entry Results"); + + if ($serno == 0) + die("the board serial number was not specified"); + + if (!isset($logno) || $logno == 0) + die("log number not specified!"); + + $query="update log set"; + + if (isset($date)) { + list($y, $m, $d) = split("-", $date); + if (!checkdate($m, $d, $y) || $y < 1999) + die("date is invalid (input '$date', " . + "yyyy-mm-dd '$y-$m-$d')"); + $query.=" date='$date'"; + } + + if (isset($details)) + $query.=", details='" . rawurlencode($details) . "'"; + + $query.=" where serno=$serno and logno=$logno"; + + mysql_query($query); + if(mysql_errno()) { + $errstr = mysql_error(); + echo "\t<font size=+4>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe following error was encountered:\n"; + echo "\t\t</p>\n"; + echo "\t\t<center>\n"; + printf("\t\t\t<b>%s</b>\n", $errstr); + echo "\t\t</center>\n"; + echo "\t</font>\n"; + } + else { + echo "\t<font size=+2>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe log entry with log number <b>$logno</b> and\n"; + echo "\t\t\tserial number <b>$serno</b> "; + echo "was successfully updated\n"; + echo "\t\t</p>\n"; + echo "\t</font>\n"; + } + +?> +<p> +<table align=center width="100%"> +<tr> + <td align=center><a href="brlog.php?serno=<?php echo "$serno"; ?>">Back to Log</a></td> + <td align=center><a href="index.php">Back to Start</a></td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/donew.php b/tools/bddb/donew.php new file mode 100644 index 0000000..0f6e0d7 --- /dev/null +++ b/tools/bddb/donew.php @@ -0,0 +1,228 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // doedit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Board Registration Results"); + + if (($serno=intval($serno)) != 0) + die("serial number must not be set ($serno) when Creating!"); + + $query="update boards set"; + + list($y, $m, $d) = split("-", $date); + if (!checkdate($m, $d, $y) || $y < 1999) + die("date is invalid (input '$date', yyyy-mm-dd '$y-$m-$d')"); + $query.=" date='$date'"; + + if ($batch != '') { + if (strlen($batch) > 32) + die("batch field too long (>32)"); + $query.=", batch='$batch'"; + } + + if (!in_array($type, $type_vals)) + die("Invalid type ($type) specified"); + $query.=", type='$type'"; + + if (($rev = intval($rev)) <= 0 || $rev > 255) + die("Revision number is invalid ($rev)"); + $query.=sprintf(", rev=%d", $rev); + + $query.=gather_enum_multi_query("sdram", 4); + + $query.=gather_enum_multi_query("flash", 4); + + $query.=gather_enum_multi_query("zbt", 16); + + $query.=gather_enum_multi_query("xlxtyp", 4); + $nxlx = count_enum_multi("xlxtyp", 4); + + $query.=gather_enum_multi_query("xlxspd", 4); + if (count_enum_multi("xlxspd", 4) != $nxlx) + die("number of xilinx speeds not same as number of types"); + + $query.=gather_enum_multi_query("xlxtmp", 4); + if (count_enum_multi("xlxtmp", 4) != $nxlx) + die("number of xilinx temps. not same as number of types"); + + $query.=gather_enum_multi_query("xlxgrd", 4); + if (count_enum_multi("xlxgrd", 4) != $nxlx) + die("number of xilinx grades not same as number of types"); + + if ($cputyp == '') { + if ($cpuspd != '') + die("can't specify cpu speed if there is no cpu"); + if ($cpmspd != '') + die("can't specify cpm speed if there is no cpu"); + if ($busspd != '') + die("can't specify bus speed if there is no cpu"); + } + else { + $query.=", cputyp='$cputyp'"; + if ($cpuspd == '') + die("must specify cpu speed if cpu type is defined"); + $query.=", cpuspd='$cpuspd'"; + if ($cpmspd == '') + die("must specify cpm speed if cpu type is defined"); + $query.=", cpmspd='$cpmspd'"; + if ($busspd == '') + die("must specify bus speed if cpu type is defined"); + $query.=", busspd='$busspd'"; + } + + if (($hschin = intval($hschin)) < 0 || $hschin > 4) + die("Invalid number of hs input chans ($hschin)"); + if (($hschout = intval($hschout)) < 0 || $hschout > 4) + die("Invalid number of hs output chans ($hschout)"); + if ($hstype == '') { + if ($hschin != 0) + die("number of high-speed input channels must be zero" + . " if high-speed chip is not present"); + if ($hschout != 0) + die("number of high-speed output channels must be zero" + . " if high-speed chip is not present"); + } + else + $query.=", hstype='$hstype'"; + $query.=", hschin='$hschin'"; + $query.=", hschout='$hschout'"; + + // echo "final query = '$query'<br>\n"; + + $quant = intval($quant); + if ($quant <= 0) $quant = 1; + + $sernos = array(); + if ($geneths) + $ethaddrs = array(); + + $sqlerr = ''; + + while ($quant-- > 0) { + + mysql_query("insert into boards (serno) values (null)"); + if (mysql_errno()) { + $sqlerr = mysql_error(); + break; + } + + $serno = mysql_insert_id(); + if (!$serno) { + $sqlerr = "couldn't allocate new serial number"; + break; + } + + mysql_query($query . " where serno=$serno"); + if (mysql_errno()) { + $sqlerr = mysql_error(); + break; + } + + array_push($sernos, $serno); + + if ($geneths) { + + $ethaddr = gen_eth_addr($serno); + + mysql_query("update boards set ethaddr='$ethaddr'" . + " where serno=$serno"); + if (mysql_errno()) { + $sqlerr = mysql_error(); + + array_push($ethaddrs, + "<font color=#ff0000><b>" . + "db save fail" . + "</b></font>"); + break; + } + + array_push($ethaddrs, $ethaddr); + } + } + + $nsernos = count($sernos); + + if ($nsernos > 0) { + + write_eeprom_cfg_file(); + + echo "<font size=+2>\n"; + echo "\t<p>\n"; + echo "\t\tThe following board serial numbers were" + . " successfully allocated"; + if ($numerrs > 0) + echo " (but with $numerrs cfg file error" . + ($numerrs > 1 ? "s" : "") . ")"; + echo ":\n"; + echo "\t</p>\n"; + + echo "</font>\n"; + + echo "<table align=center width=\"100%\">\n"; + echo "<tr>\n"; + echo "\t<th>Serial Number</th>\n"; + if ($numerrs > 0) + echo "\t<th>Cfg File Errs</th>\n"; + if ($geneths) + echo "\t<th>Ethernet Address</th>\n"; + echo "</tr>\n"; + + for ($i = 0; $i < $nsernos; $i++) { + + $serno = sprintf("%010d", $sernos[$i]); + + echo "<tr>\n"; + + echo "\t<td align=center><font size=+2>" . + "<b>$serno</b></font></td>\n"; + + if ($numerrs > 0) { + if (($errstr = $cfgerrs[$i]) == '') + $errstr = ' '; + echo "\t<td align=center>" . + "<font size=+2 color=#ff0000><b>" . + $errstr . + "</b></font></td>\n"; + } + + if ($geneths) { + echo "\t<td align=center>" . + "<font size=+2 color=#00ff00><b>" . + $ethaddrs[$i] . + "</b></font></td>\n"; + } + + echo "</tr>\n"; + } + + echo "</table>\n"; + } + + if ($sqlerr != '') { + echo "\t<font size=+4>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe following SQL error was encountered:\n"; + echo "\t\t</p>\n"; + echo "\t\t<center>\n"; + printf("\t\t\t<b>%s</b>\n", $sqlerr); + echo "\t\t</center>\n"; + echo "\t</font>\n"; + } + +?> +<p> +<table align=center width="100%"> +<tr> + <td align=center><a href="browse.php">Go to Browse</a></td> + <td align=center><a href="index.php">Back to Start</a></td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/donewlog.php b/tools/bddb/donewlog.php new file mode 100644 index 0000000..b00de95 --- /dev/null +++ b/tools/bddb/donewlog.php @@ -0,0 +1,76 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // doedit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Add Log Entry Results"); + + if ($serno == 0) + die("serial number not specified!"); + + if (isset($logno)) + die("log number must not be set ($logno) when Creating!"); + + $query="update log set serno=$serno"; + + list($y, $m, $d) = split("-", $date); + if (!checkdate($m, $d, $y) || $y < 1999) + die("date is invalid (input '$date', yyyy-mm-dd '$y-$m-$d')"); + $query.=", date='$date'"; + + if (isset($details)) + $query.=", details='" . rawurlencode($details) . "'"; + + // echo "final query = '$query'<br>\n"; + + $sqlerr = ''; + + mysql_query("insert into log (logno) values (null)"); + if (mysql_errno()) + $sqlerr = mysql_error(); + else { + $logno = mysql_insert_id(); + if (!$logno) + $sqlerr = "couldn't allocate new serial number"; + else { + mysql_query($query . " where logno=$logno"); + if (mysql_errno()) + $sqlerr = mysql_error(); + } + } + + if ($sqlerr == '') { + echo "<font size=+2>\n"; + echo "\t<p>\n"; + echo "\t\tA log entry with log number '$logno' was " . + "added to the board with serial number '$serno'\n"; + echo "\t</p>\n"; + echo "</font>\n"; + } + else { + echo "\t<font size=+4>\n"; + echo "\t\t<p>\n"; + echo "\t\t\tThe following SQL error was encountered:\n"; + echo "\t\t</p>\n"; + echo "\t\t<center>\n"; + printf("\t\t\t<b>%s</b>\n", $sqlerr); + echo "\t\t</center>\n"; + echo "\t</font>\n"; + } + +?> +<p></p> +<table width="100%"> +<tr> + <td align=center><a href="brlog.php?serno=<?php echo "$serno"; ?>">Go to Browse</a></td> + <td align=center><a href="index.php">Back to Start</a></td> +</tr> +</table> +<?php + pg_foot(); +?> diff --git a/tools/bddb/edit.php b/tools/bddb/edit.php new file mode 100644 index 0000000..f7d4830 --- /dev/null +++ b/tools/bddb/edit.php @@ -0,0 +1,131 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // edit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Edit Board Registration"); + + if ($serno == 0) + die("serial number not specified!"); + + $pserno = sprintf("%010d", $serno); + + echo "<center><b><font size=+2>"; + echo "Board Serial Number: $pserno"; + echo "</font></b></center>\n"; + +?> +<p> +<form action=doedit.php method=POST> +<?php + echo "<input type=hidden name=serno value=$serno>\n"; + + $r=mysql_query("select * from boards where serno=$serno"); + $row=mysql_fetch_array($r); + if(!$row) die("no record of serial number '$serno' in database"); + + begin_table(5); + + // ethaddr char(17) + print_field("ethaddr", $row, 17); + + // date date + print_field("date", $row); + + // batch char(32) + print_field("batch", $row, 32); + + // type enum('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY') + print_enum("type", $row, $type_vals); + + // rev tinyint(3) unsigned zerofill + print_field("rev", $row, 3, 'rev_filter'); + + // location char(64) + print_field("location", $row, 64); + + // comments text + print_field_multiline("comments", $row, 60, 10, 'text_filter'); + + // sdram[0-3] enum('32M','64M','128M','256M') + print_enum_multi("sdram", $row, $sdram_vals, 4, array()); + + // flash[0-3] enum('4M','8M','16M','32M','64M') + print_enum_multi("flash", $row, $flash_vals, 4, array()); + + // zbt[0-f] enum('512K','1M','2M','4M') + print_enum_multi("zbt", $row, $zbt_vals, 16, array()); + + // xlxtyp[0-3] enum('XCV300E','XCV400E','XCV600E') + print_enum_multi("xlxtyp", $row, $xlxtyp_vals, 4, array(), 1); + + // xlxspd[0-3] enum('6','7','8') + print_enum_multi("xlxspd", $row, $xlxspd_vals, 4, array(), 1); + + // xlxtmp[0-3] enum('COM','IND') + print_enum_multi("xlxtmp", $row, $xlxtmp_vals, 4, array(), 1); + + // xlxgrd[0-3] enum('NORMAL','ENGSAMP') + print_enum_multi("xlxgrd", $row, $xlxgrd_vals, 4, array(), 1); + + // cputyp enum('MPC8260') + print_enum("cputyp", $row, $cputyp_vals); + + // cpuspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ') + print_enum("cpuspd", $row, $clk_vals); + + // cpmspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ') + print_enum("cpmspd", $row, $clk_vals); + + // busspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ') + print_enum("busspd", $row, $clk_vals); + + // hstype enum('AMCC-S2064A') + print_enum("hstype", $row, $hstype_vals); + + // hschin enum('0','1','2','3','4') + print_enum("hschin", $row, $hschin_vals); + + // hschout enum('0','1','2','3','4') + print_enum("hschout", $row, $hschout_vals); + + end_table(); + + echo "<p>\n"; + echo "<center><b>"; + echo "<font color=#ff0000>WARNING: NO UNDO ON DELETE!</font>"; + echo "<br></br>\n"; + echo "<tt>[ <a href=\"dodelete.php?serno=$serno\">delete</a> ]</tt>"; + echo "</b></center>\n"; + echo "</p>\n"; +?> +<p> +<table align=center width="100%"> +<tr> + <td align=center> + <input type=submit value=Edit> + </td> + <td> + + </td> + <td align=center> + <input type=reset value=Reset> + </td> + <td> + + </td> + <td align=center> + <a href="index.php">Back to Start</a> + </td> +</tr> +</table> +</p> +</form> +<?php + pg_foot(); +?> diff --git a/tools/bddb/edlog.php b/tools/bddb/edlog.php new file mode 100644 index 0000000..f819b46 --- /dev/null +++ b/tools/bddb/edlog.php @@ -0,0 +1,81 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // edit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - Edit Board Log Entry"); + + if ($serno == 0) + die("serial number not specified!"); + + if (!isset($logno) || $logno == 0) + die("log number not specified!"); + + $pserno = sprintf("%010d", $serno); + $plogno = sprintf("%010d", $logno); + + echo "<center><b><font size=+2>"; + echo "Board Serial Number: $pserno, Log Number: $plogno"; + echo "</font></b></center>\n"; + +?> +<p> +<form action=doedlog.php method=POST> +<?php + echo "<input type=hidden name=serno value=$serno>\n"; + echo "<input type=hidden name=logno value=$logno>\n"; + + $r=mysql_query("select * from log where serno=$serno and logno=$logno"); + $row=mysql_fetch_array($r); + if(!$row) + die("no record of log entry with serial number '$serno' " . + "and log number '$logno' in database"); + + begin_table(3); + + // date date + print_field("date", $row); + + // details text + print_field_multiline("details", $row, 60, 10, 'text_filter'); + + end_table(); + + echo "<p>\n"; + echo "<center><b>"; + echo "<font color=#ff0000>WARNING: NO UNDO ON DELETE!</font>"; + echo "<br></br>\n"; + echo "<tt>[ <a href=\"dodellog.php?serno=$serno&logno=$logno\">delete</a> ]</tt>"; + echo "</b></center>\n"; + echo "</p>\n"; +?> +<p> +<table align=center width="100%"> +<tr> + <td align=center> + <input type=submit value=Edit> + </td> + <td> + + </td> + <td align=center> + <input type=reset value=Reset> + </td> + <td> + + </td> + <td align=center> + <a href="index.php">Back to Start</a> + </td> +</tr> +</table> +</p> +</form> +<?php + pg_foot(); +?> diff --git a/tools/bddb/execute.php b/tools/bddb/execute.php new file mode 100644 index 0000000..7adcfec --- /dev/null +++ b/tools/bddb/execute.php @@ -0,0 +1,37 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + if (!isset($serno)) + $serno = 0; + else + $serno = intval($serno); + + if (!isset($submit)) + $submit = "[NOT SET]"; + + switch ($submit) { + + case "New": + require("new.php"); + break; + + case "Edit": + require("edit.php"); + break; + + case "Browse": + require("browse.php"); + break; + + case "Log": + require("brlog.php"); + break; + + default: + require("badsubmit.php"); + break; + } +?> diff --git a/tools/bddb/index.php b/tools/bddb/index.php new file mode 100644 index 0000000..9d6c7f5 --- /dev/null +++ b/tools/bddb/index.php @@ -0,0 +1,38 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + require("defs.php"); + pg_head("$bddb_label"); +?> +<font size="+4"> + <form action=execute.php method=POST> + <table width="100%" cellspacing=10 cellpadding=10> + <tr> + <td align=center> + <input type=submit name=submit value="New"></input> + </td> + <td align=center> + <input type=submit name=submit value="Edit"></input> + </td> + <td align=center> + <input type=submit name=submit value="Browse"></input> + </td> + <td align=center> + <input type=submit name=submit value="Log"></input> + </td> + </tr> + <tr> + <td align=center colspan=4> + <b>Serial Number:</b> + <input type=text name=serno size=10 maxsize=10 value=""></input> + </td> + </tr> + </table> + </form> +</font> +<?php + pg_foot(); +?> diff --git a/tools/bddb/new.php b/tools/bddb/new.php new file mode 100644 index 0000000..889c6ae --- /dev/null +++ b/tools/bddb/new.php @@ -0,0 +1,121 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // edit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - New Board Registration"); +?> +<form action=donew.php method=POST> +<p></p> +<?php + // if a serial number was supplied, fetch the record + // and use its contents as defaults + if ($serno != 0) { + $r=mysql_query("select * from boards where serno=$serno"); + $row=mysql_fetch_array($r); + if(!$row)die("no record of serial number '$serno' in database"); + } + else + $row = array(); + + echo "<input type=hidden name=serno value=0>\n"; + + begin_table(5); + + // date date + print_field("date", array('date' => date("Y-m-d"))); + + // batch char(32) + print_field("batch", $row, 32); + + // type enum('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY') + print_enum("type", $row, $type_vals, 0); + + // rev tinyint(3) unsigned zerofill + print_field("rev", $row, 3, 'rev_filter'); + + // sdram[0-3] enum('32M','64M','128M','256M') + print_enum_multi("sdram", $row, $sdram_vals, 4, array(2)); + + // flash[0-3] enum('4M','8M','16M','32M','64M') + print_enum_multi("flash", $row, $flash_vals, 4, array(2)); + + // zbt[0-f] enum('512K','1M','2M','4M') + print_enum_multi("zbt", $row, $zbt_vals, 16, array(2, 2)); + + // xlxtyp[0-3] enum('XCV300E','XCV400E','XCV600E') + print_enum_multi("xlxtyp", $row, $xlxtyp_vals, 4, array(1), 1); + + // xlxspd[0-3] enum('6','7','8') + print_enum_multi("xlxspd", $row, $xlxspd_vals, 4, array(1), 1); + + // xlxtmp[0-3] enum('COM','IND') + print_enum_multi("xlxtmp", $row, $xlxtmp_vals, 4, array(1), 1); + + // xlxgrd[0-3] enum('NORMAL','ENGSAMP') + print_enum_multi("xlxgrd", $row, $xlxgrd_vals, 4, array(1), 1); + + // cputyp enum('MPC8260') + print_enum("cputyp", $row, $cputyp_vals, 1); + + // cpuspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ') + print_enum("cpuspd", $row, $clk_vals, 4); + + // cpmspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ') + print_enum("cpmspd", $row, $clk_vals, 4); + + // busspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ') + print_enum("busspd", $row, $clk_vals, 2); + + // hstype enum('AMCC-S2064A') + print_enum("hstype", $row, $hstype_vals, 1); + + // hschin enum('0','1','2','3','4') + print_enum("hschin", $row, $hschin_vals, 4); + + // hschout enum('0','1','2','3','4') + print_enum("hschout", $row, $hschout_vals, 4); + + end_table(); +?> +<p></p> +<table width="100%"> +<tr> + <td align=center colspan=3> + Allocate + <input type=text name=quant size=2 maxlength=2 value=" 1"> + board serial number(s) + </td> +</tr> +<tr> + <td align=center colspan=3> + <input type=checkbox name=geneths checked> + Generate Ethernet Address(es) + </td> +</tr> +<tr> + <td colspan=3> + + </td> +</tr> +<tr> + <td align=center> + <input type=submit value="Register Board"> + </td> + <td> + + </td> + <td align=center> + <input type=reset value="Reset Form Contents"> + </td> +</tr> +</table> +</form> +<?php + pg_foot(); +?> diff --git a/tools/bddb/newlog.php b/tools/bddb/newlog.php new file mode 100644 index 0000000..5ec42ac --- /dev/null +++ b/tools/bddb/newlog.php @@ -0,0 +1,48 @@ +<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?> +<?php + // (C) Copyright 2001 + // Murray Jensen <Murray.Jensen@cmst.csiro.au> + // CSIRO Manufacturing Science and Technology, Preston Lab + + // edit page (hymod_bddb / boards) + + require("defs.php"); + + pg_head("$bddb_label - New Log Entry"); + + if ($serno == 0) + die("serial number not specified!"); + + if (isset($logno)) + die("log number must not be specified when adding!"); +?> +<form action=donewlog.php method=POST> +<p></p> +<?php + echo "<input type=hidden name=serno value=$serno>\n"; + + begin_table(3); + + // date date + print_field("date", array('date' => date("Y-m-d"))); + + // details text + print_field_multiline("details", array(), 60, 10, 'text_filter'); + + end_table(); +?> +<p></p> +<table width="100%"> +<tr> + <td align=center> + <input type=submit value="Add Log Entry"> + </td> + <td align=center> + <input type=reset value="Reset Form Contents"> + </td> +</tr> +</table> +</form> +<?php + pg_foot(); +?> diff --git a/tools/easylogo/easylogo.c b/tools/easylogo/easylogo.c new file mode 100644 index 0000000..548e3c3 --- /dev/null +++ b/tools/easylogo/easylogo.c @@ -0,0 +1,422 @@ +/* +** Easylogo TGA->header converter +** ============================== +** (C) 2000 by Paolo Scaffardi (arsenio@tin.it) +** AIRVENT SAM s.p.a - RIMINI(ITALY) +** +** This is still under construction! +*/ + +#include <stdio.h> + +#pragma pack(1) + +/*#define ENABLE_ASCII_BANNERS */ + +typedef struct { + unsigned char id; + unsigned char ColorMapType; + unsigned char ImageTypeCode; + unsigned short ColorMapOrigin; + unsigned short ColorMapLenght; + unsigned char ColorMapEntrySize; + unsigned short ImageXOrigin; + unsigned short ImageYOrigin; + unsigned short ImageWidth; + unsigned short ImageHeight; + unsigned char ImagePixelSize; + unsigned char ImageDescriptorByte; +} tga_header_t; + +typedef struct { + unsigned char r,g,b ; +} rgb_t ; + +typedef struct { + unsigned char b,g,r ; +} bgr_t ; + +typedef struct { + unsigned char Cb,y1,Cr,y2; +} yuyv_t ; + +typedef struct { + unsigned char *data, + *palette ; + int width, + height, + pixels, + bpp, + pixel_size, + size, + palette_size, + yuyv; +} image_t ; + +void StringUpperCase (char *str) +{ + int count = strlen(str); + char c ; + + while(count--) + { + c=*str; + if ((c >= 'a')&&(c<='z')) + *str = 'A' + (c-'a'); + str++ ; + } +} + +void StringLowerCase (char *str) +{ + int count = strlen(str); + char c ; + + while(count--) + { + c=*str; + if ((c >= 'A')&&(c<='Z')) + *str = 'a' + (c-'A'); + str++ ; + } +} +void pixel_rgb_to_yuyv (rgb_t *rgb_pixel, yuyv_t *yuyv_pixel) +{ + unsigned int pR, pG, pB ; + + /* Transform (0-255) components to (0-100) */ + pR = rgb_pixel->r * 100 / 255 ; + pG = rgb_pixel->g * 100 / 255 ; + pB = rgb_pixel->b * 100 / 255 ; + + /* Calculate YUV values (0-255) from RGB beetween 0-100 */ + yuyv_pixel->y1 = yuyv_pixel->y2 = 209 * (pR + pG + pB) / 300 + 16 ; + yuyv_pixel->Cb = pB - (pR/4) - (pG*3/4) + 128 ; + yuyv_pixel->Cr = pR - (pG*3/4) - (pB/4) + 128 ; + + return ; +} + +void printlogo_rgb (rgb_t *data, int w, int h) +{ + int x,y; + for (y=0; y<h; y++) + { + for (x=0; x<w; x++, data++) + if ((data->r < 30)/*&&(data->g == 0)&&(data->b == 0)*/) + printf(" "); + else + printf("X"); + printf("\n"); + } +} + +void printlogo_yuyv (unsigned short *data, int w, int h) +{ + int x,y; + for (y=0; y<h; y++) + { + for (x=0; x<w; x++, data++) + if (*data == 0x1080) /* Because of inverted on i386! */ + printf(" "); + else + printf("X"); + printf("\n"); + } +} + +int image_load_tga (image_t *image, char *filename) +{ + FILE *file ; + tga_header_t header ; + int i; + unsigned char app ; + rgb_t *p ; + + if( ( file = fopen( filename, "rb" ) ) == NULL ) + return -1; + + fread(&header, sizeof(header), 1, file); + + image->width = header.ImageWidth ; + image->height = header.ImageHeight ; + + switch (header.ImageTypeCode){ + case 2: /* Uncompressed RGB */ + image->yuyv = 0 ; + image->palette_size = 0 ; + image->palette = NULL ; + break; + + default: + printf("Format not supported!\n"); + return -1 ; + } + + image->bpp = header.ImagePixelSize ; + image->pixel_size = ((image->bpp-1) / 8) + 1 ; + image->pixels = image->width * image->height; + image->size = image->pixels * image->pixel_size ; + image->data = malloc(image->size) ; + + if (image->bpp != 24) + { + printf("Bpp not supported: %d!\n", image->bpp); + return -1 ; + } + + fread(image->data, image->size, 1, file); + +/* Swapping R and B values */ + + p = image->data ; + for(i=0; i < image->pixels; i++, p++) + { + app = p->r ; + p->r = p->b ; + p->b = app ; + } + +/* Swapping image */ + + if(!(header.ImageDescriptorByte & 0x20)) + { + unsigned char *temp = malloc(image->size); + int linesize = image->pixel_size * image->width ; + void *dest = image->data, + *source = temp + image->size - linesize ; + + printf("S"); + if (temp == NULL) + { + printf("Cannot alloc temp buffer!\n"); + return -1; + } + + memcpy(temp, image->data, image->size); + for(i = 0; i<image->height; i++, dest+=linesize, source-=linesize) + memcpy(dest, source, linesize); + + free( temp ); + } + +#ifdef ENABLE_ASCII_BANNERS + printlogo_rgb (image->data,image->width, image->height); +#endif + + fclose (file); + return 0; +} + +int image_free (image_t *image) +{ + if(image->data != NULL) + free(image->data); + + if(image->palette != NULL) + free(image->palette); + + return 0; +} + +int image_rgb_to_yuyv (image_t *rgb_image, image_t *yuyv_image) +{ + rgb_t *rgb_ptr = (rgb_t *) rgb_image->data ; + yuyv_t yuyv ; + unsigned short *dest ; + int count = 0 ; + + yuyv_image->pixel_size = 2 ; + yuyv_image->bpp = 16 ; + yuyv_image->yuyv = 1 ; + yuyv_image->width = rgb_image->width ; + yuyv_image->height = rgb_image->height ; + yuyv_image->pixels = yuyv_image->width * yuyv_image->height ; + yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size ; + dest = (unsigned short *) (yuyv_image->data = malloc(yuyv_image->size)) ; + yuyv_image->palette = 0 ; + yuyv_image->palette_size= 0 ; + + while((count++) < rgb_image->pixels) + { + pixel_rgb_to_yuyv (rgb_ptr++, &yuyv); + + if ((count & 1)==0) /* Was == 0 */ + memcpy (dest, ((void *)&yuyv) + 2, sizeof(short)); + else + memcpy (dest, (void *)&yuyv, sizeof(short)); + + dest ++ ; + } + +#ifdef ENABLE_ASCII_BANNERS + printlogo_yuyv (yuyv_image->data, yuyv_image->width, yuyv_image->height); +#endif + return 0 ; +} + +int image_save_header (image_t *image, char *filename, char *varname) +{ + FILE *file = fopen (filename, "w"); + char app[256], str[256]="", def_name[64] ; + int count = image->size, col=0; + unsigned char *dataptr = image->data ; + if (file==NULL) + return -1 ; + +/* Author informations */ + fprintf(file, "/*\n * Generated by EasyLogo, (C) 2000 by Paolo Scaffardi\n/*\n"); */ + fprintf(file, " * To use this, include it and call: easylogo_plot(screen,&%s, width,x,y)\n *\n", varname); + fprintf(file, " * Where:\t'screen'\tis the pointer to the frame buffer\n"); + fprintf(file, " *\t\t'width'\tis the screen width\n"); + fprintf(file, " *\t\t'x'\t\tis the horizontal position\n"); + fprintf(file, " *\t\t'y'\t\tis the vertical position\n */\n\n"); + +/* Headers */ + fprintf(file, "#include <video_easylogo.h>\n\n"); +/* Macros */ + strcpy(def_name, varname); + StringUpperCase (def_name); + fprintf(file, "#define DEF_%s_WIDTH\t\t%d\n", def_name, image->width); + fprintf(file, "#define DEF_%s_HEIGHT\t\t%d\n", def_name, image->height); + fprintf(file, "#define DEF_%s_PIXELS\t\t%d\n", def_name, image->pixels); + fprintf(file, "#define DEF_%s_BPP\t\t%d\n", def_name, image->bpp); + fprintf(file, "#define DEF_%s_PIXEL_SIZE\t%d\n", def_name, image->pixel_size); + fprintf(file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name, image->size); +/* Declaration */ + fprintf(file, "unsigned char DEF_%s_DATA[DEF_%s_SIZE] = {\n", def_name, def_name); + +/* Data */ + while(count) + switch (col){ + case 0: + sprintf(str, " 0x%02x", *dataptr++); + col++; + count-- ; + break; + + case 16: + fprintf(file, "%s", str); + if (count > 0) + fprintf(file,","); + fprintf(file, "\n"); + + col = 0 ; + break; + + default: + strcpy(app, str); + sprintf(str, "%s, 0x%02x", app, *dataptr++); + col++ ; + count-- ; + break; + } + + if (col) + fprintf(file, "%s\n", str); + +/* End of declaration */ + fprintf(file, "};\n\n"); +/* Variable */ + fprintf(file, "fastimage_t %s = {\n", varname); + fprintf(file, " DEF_%s_DATA,\n", def_name); + fprintf(file, " DEF_%s_WIDTH,\n", def_name); + fprintf(file, " DEF_%s_HEIGHT,\n", def_name); + fprintf(file, " DEF_%s_BPP,\n", def_name); + fprintf(file, " DEF_%s_PIXEL_SIZE,\n", def_name); + fprintf(file, " DEF_%s_SIZE\n};\n", def_name); + + fclose (file); + + return 0 ; +} + +#define DEF_FILELEN 256 + +int main (int argc, char *argv[]) +{ + char + inputfile[DEF_FILELEN], + outputfile[DEF_FILELEN], + varname[DEF_FILELEN]; + + image_t rgb_logo, yuyv_logo ; + + switch (argc){ + case 2: + case 3: + case 4: + strcpy (inputfile, argv[1]); + + if (argc > 2) + strcpy (varname, argv[2]); + else + { + int pos = strchr(inputfile, '.'); + + if (pos >= 0) + { + strncpy (varname, inputfile, pos); + varname[pos] = 0 ; + } + } + + if (argc > 3) + strcpy (outputfile, argv[3]); + else + { + int pos = strchr (varname, '.'); + + if (pos > 0) + { + char app[DEF_FILELEN] ; + + strncpy(app, varname, pos); + sprintf(outputfile, "%s.h", app); + } + } + break; + + default: + printf("EasyLogo 1.0 (C) 2000 by Paolo Scaffardi\n\n"); + + printf("Syntax: easylogo inputfile [outputvar {outputfile}] \n"); + printf("\n"); + printf("Where: 'inputfile' is the TGA image to load\n"); + printf(" 'outputvar' is the variable name to create\n"); + printf(" 'outputfile' is the output header file (default is 'inputfile.h')\n"); + + return -1 ; + } + + printf("Doing '%s' (%s) from '%s'...", + outputfile, varname, inputfile); + +/* Import TGA logo */ + + printf("L"); + if (image_load_tga (&rgb_logo, inputfile)<0) + { + printf("input file not found!\n"); + exit(1); + } + +/* Convert it to YUYV format */ + + printf("C"); + image_rgb_to_yuyv (&rgb_logo, &yuyv_logo) ; + +/* Save it into a header format */ + + printf("S"); + image_save_header (&yuyv_logo, outputfile, varname) ; + +/* Free original image and copy */ + + image_free (&rgb_logo); + image_free (&yuyv_logo); + + printf("\n"); + + return 0 ; +} |