diff options
Diffstat (limited to 'qemu/roms/u-boot/board/esd/common')
22 files changed, 5052 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/esd/common/auto_update.c b/qemu/roms/u-boot/board/esd/common/auto_update.c new file mode 100644 index 000000000..85c3567b0 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/auto_update.c @@ -0,0 +1,484 @@ +/* + * (C) Copyright 2003-2004 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de. + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#include <command.h> +#include <image.h> +#include <asm/byteorder.h> +#include <fat.h> +#include <part.h> + +#include "auto_update.h" + +#ifdef CONFIG_AUTO_UPDATE + +#if !defined(CONFIG_CMD_FAT) +#error "must define CONFIG_CMD_FAT" +#endif + +extern au_image_t au_image[]; +extern int N_AU_IMAGES; + +/* where to load files into memory */ +#define LOAD_ADDR ((unsigned char *)0x100000) +#define MAX_LOADSZ 0x1c00000 + +/* externals */ +extern int fat_register_device(block_dev_desc_t *, int); +extern int file_fat_detectfs(void); +extern long file_fat_read(const char *, void *, unsigned long); +long do_fat_read (const char *filename, void *buffer, + unsigned long maxsize, int dols); +extern int flash_sect_erase(ulong, ulong); +extern int flash_sect_protect (int, ulong, ulong); +extern int flash_write (char *, ulong, ulong); + +extern block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; + +int au_check_cksum_valid(int i, long nbytes) +{ + image_header_t *hdr; + + hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + + if ((au_image[i].type == AU_FIRMWARE) && + (au_image[i].size != image_get_data_size (hdr))) { + printf ("Image %s has wrong size\n", au_image[i].name); + return -1; + } + + if (nbytes != (image_get_image_size (hdr))) { + printf ("Image %s bad total SIZE\n", au_image[i].name); + return -1; + } + + /* check the data CRC */ + if (!image_check_dcrc (hdr)) { + printf ("Image %s bad data checksum\n", au_image[i].name); + return -1; + } + return 0; +} + +int au_check_header_valid(int i, long nbytes) +{ + image_header_t *hdr; + + hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + + /* check the easy ones first */ + if (nbytes < image_get_header_size ()) { + printf ("Image %s bad header SIZE\n", au_image[i].name); + return -1; + } + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { + printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name); + return -1; + } + if (!image_check_hcrc (hdr)) { + printf ("Image %s bad header checksum\n", au_image[i].name); + return -1; + } + + /* check the type - could do this all in one gigantic if() */ + if (((au_image[i].type & AU_TYPEMASK) == AU_FIRMWARE) && + !image_check_type (hdr, IH_TYPE_FIRMWARE)) { + printf ("Image %s wrong type\n", au_image[i].name); + return -1; + } + if (((au_image[i].type & AU_TYPEMASK) == AU_SCRIPT) && + !image_check_type (hdr, IH_TYPE_SCRIPT)) { + printf ("Image %s wrong type\n", au_image[i].name); + return -1; + } + + return 0; +} + +int au_do_update(int i, long sz) +{ + image_header_t *hdr; + char *addr; + long start, end; + int off, rc; + uint nbytes; + int k; + + hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + + switch (au_image[i].type & AU_TYPEMASK) { + case AU_SCRIPT: + printf("Executing script %s\n", au_image[i].name); + + /* execute a script */ + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); + /* stick a NULL at the end of the script, otherwise */ + /* parse_string_outer() runs off the end. */ + addr[image_get_data_size (hdr)] = 0; + addr += 8; + + /* + * Replace cr/lf with ; + */ + k = 0; + while (addr[k] != 0) { + if ((addr[k] == 10) || (addr[k] == 13)) { + addr[k] = ';'; + } + k++; + } + + run_command(addr, 0); + return 0; + } + + break; + + case AU_FIRMWARE: + case AU_NOR: + case AU_NAND: + start = au_image[i].start; + end = au_image[i].start + au_image[i].size - 1; + + /* + * do not update firmware when image is already in flash. + */ + if (au_image[i].type == AU_FIRMWARE) { + char *orig = (char*)start; + char *new = (char *)((char *)hdr + + image_get_header_size ()); + nbytes = image_get_data_size (hdr); + + while (--nbytes) { + if (*orig++ != *new++) { + break; + } + } + if (!nbytes) { + printf ("Skipping firmware update - " + "images are identical\n"); + break; + } + } + + /* unprotect the address range */ + if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) || + (au_image[i].type == AU_FIRMWARE)) { + flash_sect_protect (0, start, end); + } + + /* + * erase the address range. + */ + if (au_image[i].type != AU_NAND) { + printf ("Updating NOR FLASH with image %s\n", + au_image[i].name); + debug ("flash_sect_erase(%lx, %lx);\n", start, end); + flash_sect_erase (start, end); + } + + udelay(10000); + + /* strip the header - except for the kernel and ramdisk */ + if (au_image[i].type != AU_FIRMWARE) { + addr = (char *)hdr; + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); + } else { + addr = (char *)((char *)hdr + image_get_header_size ()); + off = 0; + nbytes = image_get_data_size (hdr); + } + + /* + * copy the data from RAM to FLASH + */ + if (au_image[i].type != AU_NAND) { + debug ("flash_write(%p, %lx, %x)\n", + addr, start, nbytes); + rc = flash_write ((char *)addr, start, + (nbytes + 1) & ~1); + } else { + rc = -1; + } + if (rc != 0) { + printf ("Flashing failed due to error %d\n", rc); + return -1; + } + + /* + * check the dcrc of the copy + */ + if (au_image[i].type != AU_NAND) { + rc = crc32 (0, (uchar *)(start + off), + image_get_data_size (hdr)); + } + if (rc != image_get_dcrc (hdr)) { + printf ("Image %s Bad Data Checksum After COPY\n", + au_image[i].name); + return -1; + } + + /* protect the address range */ + /* this assumes that ONLY the firmware is protected! */ + if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) || + (au_image[i].type == AU_FIRMWARE)) { + flash_sect_protect (1, start, end); + } + + break; + + default: + printf("Wrong image type selected!\n"); + } + + return 0; +} + +static void process_macros (const char *input, char *output) +{ + char c, prev; + const char *varname_start = NULL; + int inputcnt = strlen (input); + int outputcnt = CONFIG_SYS_CBSIZE; + int state = 0; /* 0 = waiting for '$' */ + /* 1 = waiting for '(' or '{' */ + /* 2 = waiting for ')' or '}' */ + /* 3 = waiting for ''' */ +#ifdef DEBUG_PARSER + char *output_start = output; + + printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", + strlen(input), input); +#endif + + prev = '\0'; /* previous character */ + + while (inputcnt && outputcnt) { + c = *input++; + inputcnt--; + + if (state != 3) { + /* remove one level of escape characters */ + if ((c == '\\') && (prev != '\\')) { + if (inputcnt-- == 0) + break; + prev = c; + c = *input++; + } + } + + switch (state) { + case 0: /* Waiting for (unescaped) $ */ + if ((c == '\'') && (prev != '\\')) { + state = 3; + break; + } + if ((c == '$') && (prev != '\\')) { + state++; + } else { + *(output++) = c; + outputcnt--; + } + break; + case 1: /* Waiting for ( */ + if (c == '(' || c == '{') { + state++; + varname_start = input; + } else { + state = 0; + *(output++) = '$'; + outputcnt--; + + if (outputcnt) { + *(output++) = c; + outputcnt--; + } + } + break; + case 2: /* Waiting for ) */ + if (c == ')' || c == '}') { + int i; + char envname[CONFIG_SYS_CBSIZE], *envval; + /* Varname # of chars */ + int envcnt = input - varname_start - 1; + + /* Get the varname */ + for (i = 0; i < envcnt; i++) { + envname[i] = varname_start[i]; + } + envname[i] = 0; + + /* Get its value */ + envval = getenv (envname); + + /* Copy into the line if it exists */ + if (envval != NULL) + while ((*envval) && outputcnt) { + *(output++) = *(envval++); + outputcnt--; + } + /* Look for another '$' */ + state = 0; + } + break; + case 3: /* Waiting for ' */ + if ((c == '\'') && (prev != '\\')) { + state = 0; + } else { + *(output++) = c; + outputcnt--; + } + break; + } + prev = c; + } + + if (outputcnt) + *output = 0; + +#ifdef DEBUG_PARSER + printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", + strlen (output_start), output_start); +#endif +} + +/* + * this is called from board_init() after the hardware has been set up + * and is usable. That seems like a good time to do this. + * Right now the return value is ignored. + */ +int do_auto_update(void) +{ + block_dev_desc_t *stor_dev = NULL; + long sz; + int i, res, cnt, old_ctrlc; + char buffer[32]; + char str[80]; + int n; + + if (ide_dev_desc[0].type != DEV_TYPE_UNKNOWN) { + stor_dev = get_dev ("ide", 0); + if (stor_dev == NULL) { + debug ("ide: unknown device\n"); + return -1; + } + } + + if (fat_register_device (stor_dev, 1) != 0) { + debug ("Unable to register ide disk 0:1\n"); + return -1; + } + + /* + * Check if magic file is present + */ + if ((n = do_fat_read (AU_MAGIC_FILE, buffer, + sizeof(buffer), LS_NO)) <= 0) { + debug ("No auto_update magic file (n=%d)\n", n); + return -1; + } + +#ifdef CONFIG_AUTO_UPDATE_SHOW + board_auto_update_show (1); +#endif + puts("\nAutoUpdate Disk detected! Trying to update system...\n"); + + /* make sure that we see CTRL-C and save the old state */ + old_ctrlc = disable_ctrlc (0); + + /* just loop thru all the possible files */ + for (i = 0; i < N_AU_IMAGES; i++) { + /* + * Try to expand the environment var in the fname + */ + process_macros (au_image[i].name, str); + strcpy (au_image[i].name, str); + + printf("Reading %s ...", au_image[i].name); + /* just read the header */ + sz = do_fat_read (au_image[i].name, LOAD_ADDR, + image_get_header_size (), LS_NO); + debug ("read %s sz %ld hdr %d\n", + au_image[i].name, sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { + puts(" not found\n"); + continue; + } + if (au_check_header_valid (i, sz) < 0) { + puts(" header not valid\n"); + continue; + } + sz = do_fat_read (au_image[i].name, LOAD_ADDR, + MAX_LOADSZ, LS_NO); + debug ("read %s sz %ld hdr %d\n", + au_image[i].name, sz, image_get_header_size ()); + if (sz <= 0 || sz <= image_get_header_size ()) { + puts(" not found\n"); + continue; + } + if (au_check_cksum_valid (i, sz) < 0) { + puts(" checksum not valid\n"); + continue; + } + puts(" done\n"); + + do { + res = au_do_update (i, sz); + /* let the user break out of the loop */ + if (ctrlc() || had_ctrlc ()) { + clear_ctrlc (); + break; + } + cnt++; + } while (res < 0); + } + + /* restore the old state */ + disable_ctrlc (old_ctrlc); + + puts("AutoUpdate finished\n\n"); +#ifdef CONFIG_AUTO_UPDATE_SHOW + board_auto_update_show (0); +#endif + + return 0; +} + +int auto_update(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + do_auto_update(); + + return 0; +} +U_BOOT_CMD( + autoupd, 1, 1, auto_update, + "Automatically update images", + "" +); +#endif /* CONFIG_AUTO_UPDATE */ diff --git a/qemu/roms/u-boot/board/esd/common/auto_update.h b/qemu/roms/u-boot/board/esd/common/auto_update.h new file mode 100644 index 000000000..be8f439e4 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/auto_update.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _AUTO_UPDATE_H_ +#define _AUTO_UPDATE_H_ + +#define MBR_MAGIC 0x07081967 +#define MBR_MAGIC_ADDR 0x100 /* offset 0x100 should be free space */ + +#define AU_MAGIC_FILE "__auto_update" + +#define AU_TYPEMASK 0x000000ff +#define AU_FLAGMASK 0xffff0000 + +#define AU_PROTECT 0x80000000 + +#define AU_SCRIPT 0x01 +#define AU_FIRMWARE (0x02 | AU_PROTECT) +#define AU_NOR 0x03 +#define AU_NAND 0x04 + +struct au_image_s { + char name[80]; + ulong start; + ulong size; + ulong type; +}; + +typedef struct au_image_s au_image_t; + +int do_auto_update(void); +#ifdef CONFIG_AUTO_UPDATE_SHOW +void board_auto_update_show(int au_active); +#endif + +#endif /* #ifndef _AUTO_UPDATE_H_ */ diff --git a/qemu/roms/u-boot/board/esd/common/cmd_loadpci.c b/qemu/roms/u-boot/board/esd/common/cmd_loadpci.c new file mode 100644 index 000000000..803179a47 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/cmd_loadpci.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2005-2008 + * Matthias Fuchs, esd GmbH Germany, matthias.fuchs@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#if !defined(CONFIG_440) +#include <asm/4xx_pci.h> +#endif + +#if defined(CONFIG_CMD_BSP) + +extern int do_source (cmd_tbl_t *, int, int, char *[]); + +#define ADDRMASK 0xfffff000 + +/* + * Command loadpci: wait for signal from host and boot image. + */ +int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u32 *ptr = 0; + int count = 0; + int count2 = 0; + char addr[16]; + char str[] = "\\|/-"; + char *local_args[2]; + u32 la, ptm1la; + +#if defined(CONFIG_440) + ptm1la = in32r(PCIL0_PTM1LA); +#else + ptm1la = in32r(PTM1LA); +#endif + while(1) { + /* + * Mark sync address + */ + ptr = (u32 *)ptm1la; + memset(ptr, 0, 0x20); + + *ptr = 0xffffffff; + puts("\nWaiting for action from pci host -"); + + /* + * Wait for host to write the start address + */ + while (*ptr == 0xffffffff) { + count++; + if (!(count % 100)) { + count2++; + putc(0x08); /* backspace */ + putc(str[count2 % 4]); + } + + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + + udelay(1000); + } + + printf("\nGot bootcode %08x: ", *ptr); + la = ptm1la + (*ptr & ADDRMASK); + sprintf(addr, "%08x", la); + + switch (*ptr & ~ADDRMASK) { + case 0: + /* + * Boot image via bootm + */ + printf("booting image at addr 0x%s ...\n", addr); + setenv("loadaddr", addr); + do_bootm(cmdtp, 0, 0, NULL); + break; + + case 1: + /* + * Boot image via "source" command + */ + printf("executing script at addr 0x%s ...\n", addr); + local_args[0] = addr; + local_args[1] = NULL; + do_source(cmdtp, 0, 1, local_args); + break; + + case 2: + /* + * Call run_cmd + */ + printf("running command at addr 0x%s ...\n", addr); + run_command((char *)la, 0); + break; + + default: + printf("unhandled boot method\n"); + break; + } + } +} + +U_BOOT_CMD( + loadpci, 1, 1, do_loadpci, + "Wait for pci bootcmd and boot it", + "" +); + +#endif diff --git a/qemu/roms/u-boot/board/esd/common/esd405ep_nand.c b/qemu/roms/u-boot/board/esd/common/esd405ep_nand.c new file mode 100644 index 000000000..f46936ca3 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/esd405ep_nand.c @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2007 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#if defined(CONFIG_CMD_NAND) +#include <asm/io.h> +#include <nand.h> + +/* + * hardware specific access to control-lines + */ +static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_CLE); + else + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_NAND_CLE); + if ( ctrl & NAND_ALE ) + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_ALE); + else + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_NAND_ALE); + if ( ctrl & NAND_NCE ) + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_NAND_CE); + else + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_CE); + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + + +/* + * read device ready pin + */ +static int esd405ep_nand_device_ready(struct mtd_info *mtdinfo) +{ + if (in_be32((void *)GPIO0_IR) & CONFIG_SYS_NAND_RDY) + return 1; + return 0; +} + + +int board_nand_init(struct nand_chip *nand) +{ + /* + * Set NAND-FLASH GPIO signals to defaults + */ + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE)); + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_CE); + + /* + * Initialize nand_chip structure + */ + nand->cmd_ctrl = esd405ep_nand_hwcontrol; + nand->dev_ready = esd405ep_nand_device_ready; + nand->ecc.mode = NAND_ECC_SOFT; + nand->chip_delay = NAND_BIG_DELAY_US; + nand->options = NAND_SAMSUNG_LP_OPTIONS; + return 0; +} +#endif diff --git a/qemu/roms/u-boot/board/esd/common/flash.c b/qemu/roms/u-boot/board/esd/common/flash.c new file mode 100644 index 000000000..e3512c78d --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/flash.c @@ -0,0 +1,659 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#ifdef __PPC__ +#include <asm/ppc4xx.h> +#endif +#include <asm/processor.h> + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * Functions + */ +static int write_word (flash_info_t *info, ulong dest, ulong data); + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + short n; + + /* set up sector start address table */ + if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) { + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); + } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) { + /* set sector offsets for bottom boot block type */ + for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */ + info->start[i] = base; + base += 8 << 10; + } + while (i < info->sector_count) { /* 64k regular sectors */ + info->start[i] = base; + base += 64 << 10; + ++i; + } + } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) { + /* set sector offsets for top boot block type */ + base += info->size; + i = info->sector_count; + for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */ + base -= 8 << 10; + --i; + info->start[i] = base; + } + while (i > 0) { /* 64k regular sectors */ + base -= 64 << 10; + --i; + info->start[i] = base; + } + } 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; + case FLASH_MAN_EXCEL: printf ("Excel Semiconductor "); 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_AM320T: printf ("AM29LV320T (32 M, top sector)\n"); + break; + case FLASH_AM320B: printf ("AM29LV320B (32 M, bottom sector)\n"); + break; + case FLASH_AMDL322T: printf ("AM29DL322T (32 M, top sector)\n"); + break; + case FLASH_AMDL322B: printf ("AM29DL322B (32 M, bottom sector)\n"); + break; + case FLASH_AMDL323T: printf ("AM29DL323T (32 M, top sector)\n"); + break; + case FLASH_AMDL323B: printf ("AM29DL323B (32 M, bottom sector)\n"); + break; + case FLASH_AM640U: printf ("AM29LV640D (64 M, uniform sector)\n"); + break; + case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); + break; + case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); + break; + case FLASH_SST320: printf ("SST39LF/VF320 (32 Mbit, uniform sector size)\n"); + break; + case FLASH_SST640: printf ("SST39LF/VF640 (64 Mbit, uniform sector size)\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) { +#ifdef CONFIG_SYS_FLASH_EMPTY_INFO + /* + * 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 "); + /* print empty and read-only info */ + printf (" %08lX%s%s", + info->start[i], + erased ? " E" : " ", + info->protect[i] ? "RO " : " "); +#else + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + 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; + short n; + CONFIG_SYS_FLASH_WORD_SIZE value; + ulong base = (ulong)addr; + volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)addr; + + /* Write auto select command: read Manufacturer ID */ + addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; + addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; + addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00900090; + + value = addr2[CONFIG_SYS_FLASH_READ0]; + + switch (value) { + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (CONFIG_SYS_FLASH_WORD_SIZE)FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_MANUFACT: + info->flash_id = FLASH_MAN_SST; + break; + case (CONFIG_SYS_FLASH_WORD_SIZE)EXCEL_MANUFACT: + info->flash_id = FLASH_MAN_EXCEL; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + + value = addr2[CONFIG_SYS_FLASH_READ1]; /* device ID */ + + switch (value) { + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400T: + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400B: + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800T: + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800B: + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160T: + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160B: + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T: + info->flash_id += FLASH_AM320T; + info->sector_count = 71; + info->size = 0x00400000; break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B: + info->flash_id += FLASH_AM320B; + info->sector_count = 71; + info->size = 0x00400000; break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322T: + info->flash_id += FLASH_AMDL322T; + info->sector_count = 71; + info->size = 0x00400000; break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322B: + info->flash_id += FLASH_AMDL322B; + info->sector_count = 71; + info->size = 0x00400000; break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323T: + info->flash_id += FLASH_AMDL323T; + info->sector_count = 71; + info->size = 0x00400000; break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323B: + info->flash_id += FLASH_AMDL323B; + info->sector_count = 71; + info->size = 0x00400000; break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV640U: + info->flash_id += FLASH_AM640U; + info->sector_count = 128; + info->size = 0x00800000; break; /* => 8 MB */ + +#if !(defined(CONFIG_ADCIOP) || defined(CONFIG_DASA_SIM)) + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF800A: + info->flash_id += FLASH_SST800A; + info->sector_count = 16; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF160A: + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF1601: + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF1602: + info->flash_id += FLASH_SST160A; + info->sector_count = 32; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF3201: + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF3202: + info->flash_id += FLASH_SST320; + info->sector_count = 64; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF6401: + case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF6402: + info->flash_id += FLASH_SST640; + info->sector_count = 128; + info->size = 0x00800000; + break; /* => 8 MB */ +#endif + + 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_TYPEMASK) == FLASH_AM640U)) { + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); + } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) { + /* set sector offsets for bottom boot block type */ + for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */ + info->start[i] = base; + base += 8 << 10; + } + while (i < info->sector_count) { /* 64k regular sectors */ + info->start[i] = base; + base += 64 << 10; + ++i; + } + } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) || + ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) { + /* set sector offsets for top boot block type */ + base += info->size; + i = info->sector_count; + for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */ + base -= 8 << 10; + --i; + info->start[i] = base; + } + while (i > 0) { /* 64k regular sectors */ + base -= 64 << 10; + --i; + info->start[i] = base; + } + } 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 CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]); + if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD) + info->protect[i] = 0; + else + info->protect[i] = addr2[CONFIG_SYS_FLASH_READ2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0]; + *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + } + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]); + volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2; + int flag, prot, sect, l_sect; + ulong start, now, last; + 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 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[sect]); + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { + addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; + addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; + addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080; + addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; + addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; + addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00500050; /* block erase */ + for (i=0; i<50; i++) + udelay(1000); /* wait 1 ms */ + } else { + if (sect == s_first) { + addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; + addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; + addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080; + addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; + addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; + } + addr2[0] = (CONFIG_SYS_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 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[l_sect]); + while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) { + if ((now = get_timer(start)) > CONFIG_SYS_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 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (CONFIG_SYS_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) +{ + ulong *data_ptr = &data; + volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]); + volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest; + volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)data_ptr; + ulong start; + int flag; + int i; + + /* 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(); + + for (i=0; i<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) + { + addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; + addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; + addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_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] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != + (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080)) { + if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + return (1); + } + } + } + + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/qemu/roms/u-boot/board/esd/common/fpga.c b/qemu/roms/u-boot/board/esd/common/fpga.c new file mode 100644 index 000000000..5c70b474d --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/fpga.c @@ -0,0 +1,261 @@ +/* + * (C) Copyright 2001-2004 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <command.h> + +/* ------------------------------------------------------------------------- */ + +#ifdef FPGA_DEBUG +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +#define MAX_ONES 226 + +#ifdef CONFIG_SYS_FPGA_PRG +# define FPGA_PRG CONFIG_SYS_FPGA_PRG /* FPGA program pin (ppc output) */ +# define FPGA_CLK CONFIG_SYS_FPGA_CLK /* FPGA clk pin (ppc output) */ +# define FPGA_DATA CONFIG_SYS_FPGA_DATA /* FPGA data pin (ppc output) */ +# define FPGA_DONE CONFIG_SYS_FPGA_DONE /* FPGA done pin (ppc input) */ +# define FPGA_INIT CONFIG_SYS_FPGA_INIT /* FPGA init pin (ppc input) */ +#else +# define FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */ +# define FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */ +# define FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */ +# define FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */ +# define FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */ +#endif + +#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */ +#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */ +#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */ + +#ifndef SET_FPGA +# define SET_FPGA(data) out_be32((void *)GPIO0_OR, data) +#endif + +#ifdef FPGA_PROG_ACTIVE_HIGH +# define FPGA_PRG_LOW FPGA_PRG +# define FPGA_PRG_HIGH 0 +#else +# define FPGA_PRG_LOW 0 +# define FPGA_PRG_HIGH FPGA_PRG +#endif + +#define FPGA_CLK_LOW 0 +#define FPGA_CLK_HIGH FPGA_CLK + +#define FPGA_DATA_LOW 0 +#define FPGA_DATA_HIGH FPGA_DATA + +#define FPGA_WRITE_1 { \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW | FPGA_DATA_HIGH); /* set clock to 0 */ \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW | FPGA_DATA_HIGH); /* set data to 1 */ \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH); /* set clock to 1 */ \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);} /* set data to 1 */ + +#define FPGA_WRITE_0 { \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW | FPGA_DATA_HIGH); /* set clock to 0 */ \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW | FPGA_DATA_LOW); /* set data to 0 */ \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_LOW); /* set clock to 1 */ \ + SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);} /* set data to 1 */ + +#ifndef FPGA_DONE_STATE +# define FPGA_DONE_STATE (in_be32((void *)GPIO0_IR) & FPGA_DONE) +#endif +#ifndef FPGA_INIT_STATE +# define FPGA_INIT_STATE (in_be32((void *)GPIO0_IR) & FPGA_INIT) +#endif + + +static int fpga_boot (const unsigned char *fpgadata, int size) +{ + int i, index, len; + int count; + unsigned char b; + +#ifdef CONFIG_SYS_FPGA_SPARTAN2 + int j; +#else + int bit; +#endif + + /* display infos on fpgaimage */ + index = 15; + for (i = 0; i < 4; i++) { + len = fpgadata[index]; + DBG ("FPGA: %s\n", &(fpgadata[index + 1])); + index += len + 3; + } + +#ifdef CONFIG_SYS_FPGA_SPARTAN2 + /* search for preamble 0xFFFFFFFF */ + while (1) { + if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff) + && (fpgadata[index + 2] == 0xff) + && (fpgadata[index + 3] == 0xff)) + break; /* preamble found */ + else + index++; + } +#else + /* search for preamble 0xFF2X */ + for (index = 0; index < size - 1; index++) { + if ((fpgadata[index] == 0xff) + && ((fpgadata[index + 1] & 0xf0) == 0x30)) + break; + } + index += 2; +#endif + + DBG ("FPGA: configdata starts at position 0x%x\n", index); + DBG ("FPGA: length of fpga-data %d\n", size - index); + + /* + * Setup port pins for fpga programming + */ +#ifndef CONFIG_M5249 + out_be32 ((void *)GPIO0_ODR, 0x00000000); /* no open drain pins */ + /* setup for output */ + out_be32 ((void *)GPIO0_TCR, + in_be32 ((void *)GPIO0_TCR) | + FPGA_PRG | FPGA_CLK | FPGA_DATA); +#endif + SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH); /* set pins to high */ + + DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); + DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + + /* + * Init fpga by asserting and deasserting PROGRAM* + */ + SET_FPGA (FPGA_PRG_LOW | FPGA_CLK_HIGH | FPGA_DATA_HIGH); /* set prog active */ + + /* Wait for FPGA init line low */ + count = 0; + while (FPGA_INIT_STATE) { + udelay (1000); /* wait 1ms */ + /* Check for timeout - 100us max, so use 3ms */ + if (count++ > 3) { + DBG ("FPGA: Booting failed!\n"); + return ERROR_FPGA_PRG_INIT_LOW; + } + } + + DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); + DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + + /* deassert PROGRAM* */ + SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH); /* set prog inactive */ + + /* Wait for FPGA end of init period . */ + count = 0; + while (!(FPGA_INIT_STATE)) { + udelay (1000); /* wait 1ms */ + /* Check for timeout */ + if (count++ > 3) { + DBG ("FPGA: Booting failed!\n"); + return ERROR_FPGA_PRG_INIT_HIGH; + } + } + + DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); + DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + + DBG ("write configuration data into fpga\n"); + /* write configuration-data into fpga... */ + +#ifdef CONFIG_SYS_FPGA_SPARTAN2 + /* + * Load uncompressed image into fpga + */ + for (i = index; i < size; i++) { + b = fpgadata[i]; + for (j = 0; j < 8; j++) { + if ((b & 0x80) == 0x80) { + FPGA_WRITE_1; + } else { + FPGA_WRITE_0; + } + b <<= 1; + } + } +#else + /* send 0xff 0x20 */ + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_1; + FPGA_WRITE_0; + FPGA_WRITE_0; + FPGA_WRITE_1; + FPGA_WRITE_0; + FPGA_WRITE_0; + FPGA_WRITE_0; + FPGA_WRITE_0; + FPGA_WRITE_0; + + /* + ** Bit_DeCompression + ** Code 1 .. maxOnes : n '1's followed by '0' + ** maxOnes + 1 .. maxOnes + 1 : n - 1 '1's no '0' + ** maxOnes + 2 .. 254 : n - (maxOnes + 2) '0's followed by '1' + ** 255 : '1' + */ + + for (i = index; i < size; i++) { + b = fpgadata[i]; + if ((b >= 1) && (b <= MAX_ONES)) { + for (bit = 0; bit < b; bit++) { + FPGA_WRITE_1; + } + FPGA_WRITE_0; + } else if (b == (MAX_ONES + 1)) { + for (bit = 1; bit < b; bit++) { + FPGA_WRITE_1; + } + } else if ((b >= (MAX_ONES + 2)) && (b <= 254)) { + for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) { + FPGA_WRITE_0; + } + FPGA_WRITE_1; + } else if (b == 255) { + FPGA_WRITE_1; + } + } +#endif + + DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); + DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + + /* + * Check if fpga's DONE signal - correctly booted ? + */ + + /* Wait for FPGA end of programming period . */ + count = 0; + while (!(FPGA_DONE_STATE)) { + udelay (1000); /* wait 1ms */ + /* Check for timeout */ + if (count++ > 3) { + DBG ("FPGA: Booting failed!\n"); + return ERROR_FPGA_PRG_DONE; + } + } + + DBG ("FPGA: Booting successful!\n"); + return 0; +} diff --git a/qemu/roms/u-boot/board/esd/common/lcd.c b/qemu/roms/u-boot/board/esd/common/lcd.c new file mode 100644 index 000000000..22a59e448 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/lcd.c @@ -0,0 +1,359 @@ +/* + * (C) Copyright 2003-2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "asm/io.h" +#include "lcd.h" + + +extern int video_display_bitmap (ulong, int, int); + + +int palette_index; +int palette_value; +int lcd_depth; +unsigned char *glob_lcd_reg; +unsigned char *glob_lcd_mem; + +#if defined(CONFIG_SYS_LCD_ENDIAN) +void lcd_setup(int lcd, int config) +{ + if (lcd == 0) { + /* + * Set endianess and reset lcd controller 0 (small) + */ + + /* set reset to low */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD0_RST); + udelay(10); /* wait 10us */ + if (config == 1) { + /* big-endian */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN); + } else { + /* little-endian */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD_ENDIAN); + } + udelay(10); /* wait 10us */ + /* set reset to high */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD0_RST); + } else { + /* + * Set endianess and reset lcd controller 1 (big) + */ + + /* set reset to low */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD1_RST); + udelay(10); /* wait 10us */ + if (config == 1) { + /* big-endian */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN); + } else { + /* little-endian */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD_ENDIAN); + } + udelay(10); /* wait 10us */ + /* set reset to high */ + out_be32((void*)GPIO0_OR, + in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD1_RST); + } + + /* + * CONFIG_SYS_LCD_ENDIAN may also be FPGA_RESET, so set inactive + */ + out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN); +} +#endif /* CONFIG_SYS_LCD_ENDIAN */ + + +int lcd_bmp(uchar *logo_bmp) +{ + int i; + uchar *ptr; + ushort *ptr2; + ushort val; + unsigned char *dst = NULL; + int x, y; + int width, height, bpp, colors, line_size; + int header_size; + unsigned char *bmp; + unsigned char r, g, b; + BITMAPINFOHEADER *bm_info; + ulong len; + + /* + * Check for bmp mark 'BM' + */ + if (*(ushort *)logo_bmp != 0x424d) { + /* + * Decompress bmp image + */ + len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE; + dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE); + if (dst == NULL) { + printf("Error: malloc for gunzip failed!\n"); + return 1; + } + if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, + (uchar *)logo_bmp, &len) != 0) { + free(dst); + return 1; + } + if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) { + printf("Image could be truncated" + " (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n"); + } + + /* + * Check for bmp mark 'BM' + */ + if (*(ushort *)dst != 0x424d) { + printf("LCD: Unknown image format!\n"); + free(dst); + return 1; + } + } else { + /* + * Uncompressed BMP image, just use this pointer + */ + dst = (uchar *)logo_bmp; + } + + /* + * Get image info from bmp-header + */ + bm_info = (BITMAPINFOHEADER *)(dst + 14); + bpp = LOAD_SHORT(bm_info->biBitCount); + width = LOAD_LONG(bm_info->biWidth); + height = LOAD_LONG(bm_info->biHeight); + switch (bpp) { + case 1: + colors = 1; + line_size = width >> 3; + break; + case 4: + colors = 16; + line_size = width >> 1; + break; + case 8: + colors = 256; + line_size = width; + break; + case 24: + colors = 0; + line_size = width * 3; + break; + default: + printf("LCD: Unknown bpp (%d) im image!\n", bpp); + if ((dst != NULL) && (dst != (uchar *)logo_bmp)) + free(dst); + return 1; + } + printf(" (%d*%d, %dbpp)\n", width, height, bpp); + + /* + * Write color palette + */ + if ((colors <= 256) && (lcd_depth <= 8)) { + ptr = (unsigned char *)(dst + 14 + 40); + for (i = 0; i < colors; i++) { + b = *ptr++; + g = *ptr++; + r = *ptr++; + ptr++; + S1D_WRITE_PALETTE(glob_lcd_reg, i, r, g, b); + } + } + + /* + * Write bitmap data into framebuffer + */ + ptr = glob_lcd_mem; + ptr2 = (ushort *)glob_lcd_mem; + header_size = 14 + 40 + 4*colors; /* skip bmp header */ + for (y = 0; y < height; y++) { + bmp = &dst[(height-1-y)*line_size + header_size]; + if (lcd_depth == 16) { + if (bpp == 24) { + for (x = 0; x < width; x++) { + /* + * Generate epson 16bpp fb-format + * from 24bpp image + */ + b = *bmp++ >> 3; + g = *bmp++ >> 2; + r = *bmp++ >> 3; + val = ((r & 0x1f) << 11) | + ((g & 0x3f) << 5) | + (b & 0x1f); + *ptr2++ = val; + } + } else if (bpp == 8) { + for (x = 0; x < line_size; x++) { + /* query rgb value from palette */ + ptr = (unsigned char *)(dst + 14 + 40); + ptr += (*bmp++) << 2; + b = *ptr++ >> 3; + g = *ptr++ >> 2; + r = *ptr++ >> 3; + val = ((r & 0x1f) << 11) | + ((g & 0x3f) << 5) | + (b & 0x1f); + *ptr2++ = val; + } + } + } else { + for (x = 0; x < line_size; x++) + *ptr++ = *bmp++; + } + } + + if ((dst != NULL) && (dst != (uchar *)logo_bmp)) + free(dst); + return 0; +} + + +int lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, + uchar *logo_bmp, ulong len) +{ + int i; + ushort s1dReg; + uchar s1dValue; + int reg_byte_swap; + + /* + * Detect epson + */ + out_8(&lcd_reg[0], 0x00); + out_8(&lcd_reg[1], 0x00); + + if (in_8(&lcd_reg[0]) == 0x1c) { + /* + * Big epson detected + */ + reg_byte_swap = false; + palette_index = 0x1e2; + palette_value = 0x1e4; + lcd_depth = 16; + puts("LCD: S1D13806"); + } else if (in_8(&lcd_reg[1]) == 0x1c) { + /* + * Big epson detected (with register swap bug) + */ + reg_byte_swap = true; + palette_index = 0x1e3; + palette_value = 0x1e5; + lcd_depth = 16; + puts("LCD: S1D13806S"); + } else if (in_8(&lcd_reg[0]) == 0x18) { + /* + * Small epson detected (704) + */ + reg_byte_swap = false; + palette_index = 0x15; + palette_value = 0x17; + lcd_depth = 8; + puts("LCD: S1D13704"); + } else if (in_8(&lcd_reg[0x10000]) == 0x24) { + /* + * Small epson detected (705) + */ + reg_byte_swap = false; + palette_index = 0x15; + palette_value = 0x17; + lcd_depth = 8; + lcd_reg += 0x10000; /* add offset for 705 regs */ + puts("LCD: S1D13705"); + } else { + out_8(&lcd_reg[0x1a], 0x00); + udelay(1000); + if (in_8(&lcd_reg[1]) == 0x0c) { + /* + * S1D13505 detected + */ + reg_byte_swap = true; + palette_index = 0x25; + palette_value = 0x27; + lcd_depth = 16; + + puts("LCD: S1D13505"); + } else { + puts("LCD: No controller detected!\n"); + return 1; + } + } + + /* + * Setup lcd controller regs + */ + for (i = 0; i < reg_count; i++) { + s1dReg = regs[i].Index; + if (reg_byte_swap) { + if ((s1dReg & 0x0001) == 0) + s1dReg |= 0x0001; + else + s1dReg &= ~0x0001; + } + s1dValue = regs[i].Value; + out_8(&lcd_reg[s1dReg], s1dValue); + } + + /* + * Save reg & mem pointer for later usage (e.g. bmp command) + */ + glob_lcd_reg = lcd_reg; + glob_lcd_mem = lcd_mem; + + /* + * Display bmp image + */ + return lcd_bmp(logo_bmp); +} + +int do_esdbmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + ulong addr; +#ifdef CONFIG_VIDEO_SM501 + char *str; +#endif + if (argc != 2) + return cmd_usage(cmdtp); + + addr = simple_strtoul(argv[1], NULL, 16); + +#ifdef CONFIG_VIDEO_SM501 + str = getenv("bd_type"); + if ((strcmp(str, "ppc221") == 0) || (strcmp(str, "ppc231") == 0)) { + /* + * SM501 available, use standard bmp command + */ + return video_display_bitmap(addr, 0, 0); + } else { + /* + * No SM501 available, use esd epson bmp command + */ + return lcd_bmp((uchar *)addr); + } +#else + return lcd_bmp((uchar *)addr); +#endif +} + +U_BOOT_CMD( + esdbmp, 2, 1, do_esdbmp, + "display BMP image", + "<imageAddr> - display image" +); diff --git a/qemu/roms/u-boot/board/esd/common/lcd.h b/qemu/roms/u-boot/board/esd/common/lcd.h new file mode 100644 index 000000000..5b14bf926 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/lcd.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2003-2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Neutralize little endians. + */ +#define SWAP_LONG(data) ((unsigned long) \ + (((unsigned long)(data) >> 24) | \ + ((unsigned long)(data) << 24) | \ + (((unsigned long)(data) >> 8) & 0x0000ff00 ) | \ + (((unsigned long)(data) << 8) & 0x00ff0000 ))) +#define SWAP_SHORT(data) ((unsigned short) \ + (((unsigned short)(data) >> 8 ) | \ + ((unsigned short)(data) << 8 ))) +#define LOAD_LONG(data) SWAP_LONG(data) +#define LOAD_SHORT(data) SWAP_SHORT(data) + +#define S1D_WRITE_PALETTE(p,i,r,g,b) \ + { \ + out_8(&((uchar*)(p))[palette_index], (uchar)(i)); \ + out_8(&((uchar*)(p))[palette_index], (uchar)(r)); \ + out_8(&((uchar*)(p))[palette_index], (uchar)(g)); \ + out_8(&((uchar*)(p))[palette_index], (uchar)(b)); \ + } + +typedef struct +{ + ushort Index; + uchar Value; +} S1D_REGS; + +typedef struct /**** BMP file info structure ****/ +{ + unsigned int biSize; /* Size of info header */ + int biWidth; /* Width of image */ + int biHeight; /* Height of image */ + unsigned short biPlanes; /* Number of color planes */ + unsigned short biBitCount; /* Number of bits per pixel */ + unsigned int biCompression; /* Type of compression to use */ + unsigned int biSizeImage; /* Size of image data */ + int biXPelsPerMeter; /* X pixels per meter */ + int biYPelsPerMeter; /* Y pixels per meter */ + unsigned int biClrUsed; /* Number of colors used */ + unsigned int biClrImportant; /* Number of important colors */ +} BITMAPINFOHEADER; diff --git a/qemu/roms/u-boot/board/esd/common/misc.c b/qemu/roms/u-boot/board/esd/common/misc.c new file mode 100644 index 000000000..79cd61273 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/misc.c @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#ifdef CONFIG_LXT971_NO_SLEEP +#include <miiphy.h> +#endif + + +#ifdef CONFIG_LXT971_NO_SLEEP +void lxt971_no_sleep(void) +{ + unsigned short reg; + + miiphy_read("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, ®); + reg &= ~0x0040; /* disable sleep mode */ + miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, reg); +} +#endif /* CONFIG_LXT971_NO_SLEEP */ diff --git a/qemu/roms/u-boot/board/esd/common/pci.c b/qemu/roms/u-boot/board/esd/common/pci.c new file mode 100644 index 000000000..faebdb182 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/pci.c @@ -0,0 +1,186 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/processor.h> +#include <pci.h> + + +u_long pci9054_iobase; + + +#define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */ +#define PCI_PRIMARY_CDR (0x80000000) /* PCI config data reg */ + + +/*-----------------------------------------------------------------------------+ +| Subroutine: pci9054_read_config_dword +| Description: Read a PCI configuration register +| Inputs: +| hose PCI Controller +| dev PCI Bus+Device+Function number +| offset Configuration register number +| value Address of the configuration register value +| Return value: +| 0 Successful ++-----------------------------------------------------------------------------*/ +int pci9054_read_config_dword(struct pci_controller *hose, + pci_dev_t dev, int offset, u32* value) +{ + unsigned long conAdrVal; + unsigned long val; + + /* generate coded value for CON_ADR register */ + conAdrVal = dev | (offset & 0xfc) | 0x80000000; + + /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */ + *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal; + + /* Note: *pResult comes back as -1 if machine check happened */ + val = in32r(PCI_PRIMARY_CDR); + + *value = (unsigned long) val; + + out32r(PCI_PRIMARY_CAR, 0); + + if ((*(unsigned long *)0x50000304) & 0x60000000) + { + /* clear pci master/target abort bits */ + *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304; + } + + return 0; +} + +/*-----------------------------------------------------------------------------+ +| Subroutine: pci9054_write_config_dword +| Description: Write a PCI configuration register. +| Inputs: +| hose PCI Controller +| dev PCI Bus+Device+Function number +| offset Configuration register number +| Value Configuration register value +| Return value: +| 0 Successful +| Updated for pass2 errata #6. Need to disable interrupts and clear the +| PCICFGADR reg after writing the PCICFGDATA reg. ++-----------------------------------------------------------------------------*/ +int pci9054_write_config_dword(struct pci_controller *hose, + pci_dev_t dev, int offset, u32 value) +{ + unsigned long conAdrVal; + + conAdrVal = dev | (offset & 0xfc) | 0x80000000; + + *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal; + + out32r(PCI_PRIMARY_CDR, value); + + out32r(PCI_PRIMARY_CAR, 0); + + /* clear pci master/target abort bits */ + *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304; + + return (0); +} + +/*----------------------------------------------------------------------- + */ + +#ifdef CONFIG_DASA_SIM +static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev, + struct pci_config_table *_) +{ + unsigned int iobase; + unsigned short status = 0; + unsigned char timer; + + /* + * Configure PLX PCI9054 + */ + pci_read_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, &status); + status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, status); + + /* Check the latency timer for values >= 0x60. + */ + pci_read_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer); + if (timer < 0x60) + { + pci_write_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60); + } + + /* Set I/O base register. + */ + pci_write_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CONFIG_SYS_PCI9054_IOBASE); + pci_read_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase); + + pci9054_iobase = pci_mem_to_phys(CONFIG_SYS_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK); + + if (pci9054_iobase == 0xffffffff) + { + printf("Error: Can not set I/O base register.\n"); + return; + } +} +#endif + +static struct pci_config_table pci9054_config_table[] = { +#ifndef CONFIG_PCI_PNP + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_BUS(CONFIG_SYS_ETH_DEV_FN), PCI_DEV(CONFIG_SYS_ETH_DEV_FN), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN), + pci_cfgfunc_config_device, { CONFIG_SYS_ETH_IOBASE, + CONFIG_SYS_ETH_IOBASE, + PCI_COMMAND_IO | PCI_COMMAND_MASTER }}, +#ifdef CONFIG_DASA_SIM + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN), + pci_dasa_sim_config_pci9054 }, +#endif +#endif + { } +}; + +static struct pci_controller pci9054_hose = { + config_table: pci9054_config_table, +}; + +void pci_init_board(void) +{ + struct pci_controller *hose = &pci9054_hose; + + /* + * Register the hose + */ + hose->first_busno = 0; + hose->last_busno = 0xff; + + /* System memory space */ + pci_set_region(hose->regions + 0, + 0x00000000, 0x00000000, 0x01000000, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + /* PCI Memory space */ + pci_set_region(hose->regions + 1, + 0x00000000, 0xc0000000, 0x10000000, + PCI_REGION_MEM); + + pci_set_ops(hose, + pci_hose_read_config_byte_via_dword, + pci_hose_read_config_word_via_dword, + pci9054_read_config_dword, + pci_hose_write_config_byte_via_dword, + pci_hose_write_config_word_via_dword, + pci9054_write_config_dword); + + hose->region_count = 2; + + pci_register_hose(hose); + + hose->last_busno = pci_hose_scan(hose); +} diff --git a/qemu/roms/u-boot/board/esd/common/s1d13505_640_480_16bpp.h b/qemu/roms/u-boot/board/esd/common/s1d13505_640_480_16bpp.h new file mode 100644 index 000000000..ca11683a2 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/s1d13505_640_480_16bpp.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2008 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Panel: 640x480 50Hz TFT Single 18-bit (PCLK=20.000 MHz) + * Memory: DRAM (MCLK=40.000 MHz) + */ +static S1D_REGS regs_13505_640_480_16bpp[] = +{ + {0x1B,0x00}, /* Miscellaneous Register */ + {0x23,0x20}, /* Performance Enhancement Register 1 */ + {0x01,0x30}, /* Memory Configuration Register */ + {0x22,0x24}, /* Performance Enhancement Register 0 */ + {0x02,0x25}, /* Panel Type Register */ + {0x03,0x00}, /* MOD Rate Register */ + {0x04,0x4F}, /* Horizontal Display Width Register */ + {0x05,0x0c}, /* Horizontal Non-Display Period Register */ + {0x06,0x00}, /* HRTC/FPLINE Start Position Register */ + {0x07,0x01}, /* HRTC/FPLINE Pulse Width Register */ + {0x08,0xDF}, /* Vertical Display Height Register 0 */ + {0x09,0x01}, /* Vertical Display Height Register 1 */ + {0x0A,0x3E}, /* Vertical Non-Display Period Register */ + {0x0B,0x00}, /* VRTC/FPFRAME Start Position Register */ + {0x0C,0x01}, /* VRTC/FPFRAME Pulse Width Register */ + {0x0E,0xFF}, /* Screen 1 Line Compare Register 0 */ + {0x0F,0x03}, /* Screen 1 Line Compare Register 1 */ + {0x10,0x00}, /* Screen 1 Display Start Address Register 0 */ + {0x11,0x00}, /* Screen 1 Display Start Address Register 1 */ + {0x12,0x00}, /* Screen 1 Display Start Address Register 2 */ + {0x13,0x00}, /* Screen 2 Display Start Address Register 0 */ + {0x14,0x00}, /* Screen 2 Display Start Address Register 1 */ + {0x15,0x00}, /* Screen 2 Display Start Address Register 2 */ + {0x16,0x80}, /* Memory Address Offset Register 0 */ + {0x17,0x02}, /* Memory Address Offset Register 1 */ + {0x18,0x00}, /* Pixel Panning Register */ + {0x19,0x01}, /* Clock Configuration Register */ + {0x1A,0x00}, /* Power Save Configuration Register */ + {0x1C,0x00}, /* MD Configuration Readback Register 0 */ + {0x1E,0x06}, /* General IO Pins Configuration Register 0 */ + {0x1F,0x00}, /* General IO Pins Configuration Register 1 */ + {0x20,0x00}, /* General IO Pins Control Register 0 */ + {0x21,0x00}, /* General IO Pins Control Register 1 */ + {0x23,0x20}, /* Performance Enhancement Register 1 */ + {0x0D,0x15}, /* Display Mode Register */ +}; diff --git a/qemu/roms/u-boot/board/esd/common/s1d13704_320_240_4bpp.h b/qemu/roms/u-boot/board/esd/common/s1d13704_320_240_4bpp.h new file mode 100644 index 000000000..bd910e8b2 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/s1d13704_320_240_4bpp.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Generic Header information generated by 13704CFG.EXE (Build 10) + * Panel: 320x240x4bpp 78Hz Mono 4-Bit STN, Disabled (PCLK=6.666MHz) + */ + +static S1D_REGS regs_13704_320_240_4bpp[] = +{ + { 0x00, 0x00 }, /* Revision Code Register */ + { 0x01, 0x04 }, /*00*/ /* Mode Register 0 Register */ + { 0x02, 0xA4 }, /*a0*/ /* Mode Register 1 Register */ + { 0x03, 0x83 }, /*03*/ /* Mode Register 2 Register - bit7 is LUT bypass */ + { 0x04, 0x27 }, /* Horizontal Panel Size Register */ + { 0x05, 0xEF }, /* Vertical Panel Size Register (LSB) */ + { 0x06, 0x00 }, /* Vertical Panel Size Register (MSB) */ + { 0x07, 0x00 }, /* FPLINE Start Position Register */ + { 0x08, 0x00 }, /* Horizontal Non-Display Period Register */ + { 0x09, 0x00 }, /* FPFRAME Start Position Register */ + { 0x0A, 0x02 }, /* Vertical Non-Display Period Register */ + { 0x0B, 0x00 }, /* MOD Rate Register */ + { 0x0C, 0x00 }, /* Screen 1 Start Address Register (LSB) */ + { 0x0D, 0x00 }, /* Screen 1 Start Address Register (MSB) */ + { 0x0E, 0x00 }, /* Not Used */ + { 0x0F, 0x00 }, /* Screen 2 Start Address Register (LSB) */ + { 0x10, 0x00 }, /* Screen 2 Start Address Register (MSB) */ + { 0x11, 0x00 }, /* Not Used */ + { 0x12, 0x00 }, /* Memory Address Offset Register */ + { 0x13, 0xFF }, /* Screen 1 Vertical Size Register (LSB) */ + { 0x14, 0x03 }, /* Screen 1 Vertical Size Register (MSB) */ + { 0x15, 0x00 }, /* Look-Up Table Address Register */ + { 0x16, 0x00 }, /* Look-Up Table Bank Select Register */ + { 0x17, 0x00 }, /* Look-Up Table Data Register */ + { 0x18, 0x01 }, /* GPIO Configuration Control Register */ + { 0x19, 0x01 }, /* GPIO Status/Control Register */ + { 0x1A, 0x00 }, /* Scratch Pad Register */ + { 0x1B, 0x00 }, /* SwivelView Mode Register */ + { 0x1C, 0xA0 }, /* Line Byte Count Register */ + { 0x1D, 0x00 }, /* Not Used */ + { 0x1E, 0x00 }, /* Not Used */ + { 0x1F, 0x00 }, /* Not Used */ +}; diff --git a/qemu/roms/u-boot/board/esd/common/s1d13705_320_240_8bpp.h b/qemu/roms/u-boot/board/esd/common/s1d13705_320_240_8bpp.h new file mode 100644 index 000000000..041b4a93c --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/s1d13705_320_240_8bpp.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Generic Header information generated by 13704CFG.EXE (Build 10) + * Panel: 320x240x8bpp 78Hz Mono 8-Bit STN, Disabled (PCLK=6.666MHz) + */ + +static S1D_REGS regs_13705_320_240_8bpp[] = +{ + { 0x00, 0x00 }, /* Revision Code Register */ + { 0x01, 0x23 }, /* Mode Register 0 Register */ + { 0x02, 0xE0 }, /* Mode Register 1 Register */ + { 0x03, 0x03 }, /* Mode Register 2 Register - bit7 is LUT bypass */ + { 0x04, 0x27 }, /* Horizontal Panel Size Register */ + { 0x05, 0xEF }, /* Vertical Panel Size Register (LSB) */ + { 0x06, 0x00 }, /* Vertical Panel Size Register (MSB) */ + { 0x07, 0x00 }, /* FPLINE Start Position Register */ + { 0x08, 0x00 }, /* Horizontal Non-Display Period Register */ + { 0x09, 0x01 }, /* FPFRAME Start Position Register */ + { 0x0A, 0x02 }, /* Vertical Non-Display Period Register */ + { 0x0B, 0x00 }, /* MOD Rate Register */ + { 0x0C, 0x00 }, /* Screen 1 Start Address Register (LSB) */ + { 0x0D, 0x00 }, /* Screen 1 Start Address Register (MSB) */ + { 0x0E, 0x00 }, /* Not Used */ + { 0x0F, 0x00 }, /* Screen 2 Start Address Register (LSB) */ + { 0x10, 0x00 }, /* Screen 2 Start Address Register (MSB) */ + { 0x11, 0x00 }, /* Not Used */ + { 0x12, 0x00 }, /* Memory Address Offset Register */ + { 0x13, 0xFF }, /* Screen 1 Vertical Size Register (LSB) */ + { 0x14, 0x03 }, /* Screen 1 Vertical Size Register (MSB) */ + { 0x15, 0x00 }, /* Look-Up Table Address Register */ + { 0x16, 0x00 }, /* Look-Up Table Bank Select Register */ + { 0x17, 0x00 }, /* Look-Up Table Data Register */ + { 0x18, 0x01 }, /* GPIO Configuration Control Register */ + { 0x19, 0x01 }, /* GPIO Status/Control Register */ + { 0x1A, 0x00 }, /* Scratch Pad Register */ + { 0x1B, 0x00 }, /* SwivelView Mode Register */ + { 0x1C, 0xFF }, /* Line Byte Count Register */ + { 0x1D, 0x00 }, /* Not Used */ + { 0x1E, 0x00 }, /* Not Used */ + { 0x1F, 0x00 }, /* Not Used */ +}; diff --git a/qemu/roms/u-boot/board/esd/common/s1d13806_1024_768_8bpp.h b/qemu/roms/u-boot/board/esd/common/s1d13806_1024_768_8bpp.h new file mode 100644 index 000000000..615fa33a3 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/s1d13806_1024_768_8bpp.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * File generated by S1D13806CFG.EXE + * Panel: (active) 1024x768 34Hz TFT Single 12-bit (PCLK=BUSCLK=33.333MHz) + * Memory: Embedded SDRAM (MCLK=CLKI=49.100MHz) (BUSCLK=33.333MHz) + */ + +static S1D_REGS regs_13806_1024_768_8bpp[] = +{ + {0x0001,0x00}, /* Miscellaneous Register */ + {0x01FC,0x00}, /* Display Mode Register */ + {0x0004,0x00}, /* General IO Pins Configuration Register 0 */ + {0x0005,0x00}, /* General IO Pins Configuration Register 1 */ + {0x0008,0x00}, /* General IO Pins Control Register 0 */ + {0x0009,0x00}, /* General IO Pins Control Register 1 */ + {0x0010,0x00}, /* Memory Clock Configuration Register */ + {0x0014,0x01}, /* LCD Pixel Clock Configuration Register */ + {0x0018,0x00}, /* CRT/TV Pixel Clock Configuration Register */ + {0x001C,0x02}, /* MediaPlug Clock Configuration Register */ + {0x001E,0x01}, /* CPU To Memory Wait State Select Register */ + {0x0021,0x03}, /* DRAM Refresh Rate Register */ + {0x002A,0x00}, /* DRAM Timings Control Register 0 */ + {0x002B,0x01}, /* DRAM Timings Control Register 1 */ + {0x0020,0x80}, /* Memory Configuration Register */ + {0x0030,0x55}, /* Panel Type Register */ + {0x0031,0x00}, /* MOD Rate Register */ + {0x0032,0x7F}, /* LCD Horizontal Display Width Register */ + {0x0034,0x12}, /* LCD Horizontal Non-Display Period Register */ + {0x0035,0x01}, /* TFT FPLINE Start Position Register */ + {0x0036,0x0B}, /* TFT FPLINE Pulse Width Register */ + {0x0038,0xFF}, /* LCD Vertical Display Height Register 0 */ + {0x0039,0x02}, /* LCD Vertical Display Height Register 1 */ + {0x003A,0x2C}, /* LCD Vertical Non-Display Period Register */ + {0x003B,0x0A}, /* TFT FPFRAME Start Position Register */ + {0x003C,0x01}, /* TFT FPFRAME Pulse Width Register */ + {0x0040,0x03}, /* LCD Display Mode Register */ + {0x0041,0x00}, /* LCD Miscellaneous Register */ + {0x0042,0x00}, /* LCD Display Start Address Register 0 */ + {0x0043,0x00}, /* LCD Display Start Address Register 1 */ + {0x0044,0x00}, /* LCD Display Start Address Register 2 */ + {0x0046,0x00}, /* LCD Memory Address Offset Register 0 */ + {0x0047,0x02}, /* LCD Memory Address Offset Register 1 */ + {0x0048,0x00}, /* LCD Pixel Panning Register */ + {0x004A,0x00}, /* LCD Display FIFO High Threshold Control Register */ + {0x004B,0x00}, /* LCD Display FIFO Low Threshold Control Register */ + {0x0050,0x4F}, /* CRT/TV Horizontal Display Width Register */ + {0x0052,0x13}, /* CRT/TV Horizontal Non-Display Period Register */ + {0x0053,0x01}, /* CRT/TV HRTC Start Position Register */ + {0x0054,0x0B}, /* CRT/TV HRTC Pulse Width Register */ + {0x0056,0xDF}, /* CRT/TV Vertical Display Height Register 0 */ + {0x0057,0x01}, /* CRT/TV Vertical Display Height Register 1 */ + {0x0058,0x2B}, /* CRT/TV Vertical Non-Display Period Register */ + {0x0059,0x09}, /* CRT/TV VRTC Start Position Register */ + {0x005A,0x01}, /* CRT/TV VRTC Pulse Width Register */ + {0x005B,0x10}, /* TV Output Control Register */ + {0x0060,0x03}, /* CRT/TV Display Mode Register */ + {0x0062,0x00}, /* CRT/TV Display Start Address Register 0 */ + {0x0063,0x00}, /* CRT/TV Display Start Address Register 1 */ + {0x0064,0x00}, /* CRT/TV Display Start Address Register 2 */ + {0x0066,0x40}, /* CRT/TV Memory Address Offset Register 0 */ + {0x0067,0x01}, /* CRT/TV Memory Address Offset Register 1 */ + {0x0068,0x00}, /* CRT/TV Pixel Panning Register */ + {0x006A,0x00}, /* CRT/TV Display FIFO High Threshold Control Register */ + {0x006B,0x00}, /* CRT/TV Display FIFO Low Threshold Control Register */ + {0x0070,0x00}, /* LCD Ink/Cursor Control Register */ + {0x0071,0x01}, /* LCD Ink/Cursor Start Address Register */ + {0x0072,0x00}, /* LCD Cursor X Position Register 0 */ + {0x0073,0x00}, /* LCD Cursor X Position Register 1 */ + {0x0074,0x00}, /* LCD Cursor Y Position Register 0 */ + {0x0075,0x00}, /* LCD Cursor Y Position Register 1 */ + {0x0076,0x00}, /* LCD Ink/Cursor Blue Color 0 Register */ + {0x0077,0x00}, /* LCD Ink/Cursor Green Color 0 Register */ + {0x0078,0x00}, /* LCD Ink/Cursor Red Color 0 Register */ + {0x007A,0x1F}, /* LCD Ink/Cursor Blue Color 1 Register */ + {0x007B,0x3F}, /* LCD Ink/Cursor Green Color 1 Register */ + {0x007C,0x1F}, /* LCD Ink/Cursor Red Color 1 Register */ + {0x007E,0x00}, /* LCD Ink/Cursor FIFO Threshold Register */ + {0x0080,0x00}, /* CRT/TV Ink/Cursor Control Register */ + {0x0081,0x01}, /* CRT/TV Ink/Cursor Start Address Register */ + {0x0082,0x00}, /* CRT/TV Cursor X Position Register 0 */ + {0x0083,0x00}, /* CRT/TV Cursor X Position Register 1 */ + {0x0084,0x00}, /* CRT/TV Cursor Y Position Register 0 */ + {0x0085,0x00}, /* CRT/TV Cursor Y Position Register 1 */ + {0x0086,0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register */ + {0x0087,0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register */ + {0x0088,0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register */ + {0x008A,0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register */ + {0x008B,0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register */ + {0x008C,0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register */ + {0x008E,0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register */ + {0x0100,0x00}, /* BitBlt Control Register 0 */ + {0x0101,0x00}, /* BitBlt Control Register 1 */ + {0x0102,0x00}, /* BitBlt ROP Code/Color Expansion Register */ + {0x0103,0x00}, /* BitBlt Operation Register */ + {0x0104,0x00}, /* BitBlt Source Start Address Register 0 */ + {0x0105,0x00}, /* BitBlt Source Start Address Register 1 */ + {0x0106,0x00}, /* BitBlt Source Start Address Register 2 */ + {0x0108,0x00}, /* BitBlt Destination Start Address Register 0 */ + {0x0109,0x00}, /* BitBlt Destination Start Address Register 1 */ + {0x010A,0x00}, /* BitBlt Destination Start Address Register 2 */ + {0x010C,0x00}, /* BitBlt Memory Address Offset Register 0 */ + {0x010D,0x00}, /* BitBlt Memory Address Offset Register 1 */ + {0x0110,0x00}, /* BitBlt Width Register 0 */ + {0x0111,0x00}, /* BitBlt Width Register 1 */ + {0x0112,0x00}, /* BitBlt Height Register 0 */ + {0x0113,0x00}, /* BitBlt Height Register 1 */ + {0x0114,0x00}, /* BitBlt Background Color Register 0 */ + {0x0115,0x00}, /* BitBlt Background Color Register 1 */ + {0x0118,0x00}, /* BitBlt Foreground Color Register 0 */ + {0x0119,0x00}, /* BitBlt Foreground Color Register 1 */ + {0x01E0,0x00}, /* Look-Up Table Mode Register */ + {0x01E2,0x00}, /* Look-Up Table Address Register */ + {0x01F0,0x10}, /* Power Save Configuration Register */ + {0x01F1,0x00}, /* Power Save Status Register */ + {0x01F4,0x00}, /* CPU-to-Memory Access Watchdog Timer Register */ + {0x01FC,0x01}, /* Display Mode Register */ +}; diff --git a/qemu/roms/u-boot/board/esd/common/s1d13806_320_240_4bpp.h b/qemu/roms/u-boot/board/esd/common/s1d13806_320_240_4bpp.h new file mode 100644 index 000000000..2531f4743 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/s1d13806_320_240_4bpp.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * File generated by S1D13806CFG.EXE + * Panel: (active) 320x240 62Hz STN Single 4-bit (PCLK=CLKI2/4=6.250MHz) + * Memory: Embedded SDRAM (MCLK=CLKI=49.500MHz) (BUSCLK=33.333MHz) + */ + +static S1D_REGS regs_13806_320_240_4bpp[] = +{ + {0x0001,0x00}, /* Miscellaneous Register */ + {0x01FC,0x00}, /* Display Mode Register */ + {0x0004,0x08}, /* General IO Pins Configuration Register 0 */ + {0x0005,0x08}, /* General IO Pins Configuration Register 1 */ + {0x0008,0x08}, /* General IO Pins Control Register 0 */ + {0x0009,0x00}, /* General IO Pins Control Register 1 */ + {0x0010,0x00}, /* Memory Clock Configuration Register */ + {0x0014,0x32}, /* LCD Pixel Clock Configuration Register */ + {0x0018,0x00}, /* CRT/TV Pixel Clock Configuration Register */ + {0x001C,0x02}, /* MediaPlug Clock Configuration Register */ + {0x001E,0x01}, /* CPU To Memory Wait State Select Register */ + {0x0021,0x03}, /* DRAM Refresh Rate Register */ + {0x002A,0x00}, /* DRAM Timings Control Register 0 */ + {0x002B,0x01}, /* DRAM Timings Control Register 1 */ + {0x0020,0x80}, /* Memory Configuration Register */ + {0x0030,0x00}, /* Panel Type Register */ + {0x0031,0x00}, /* MOD Rate Register */ + {0x0032,0x27}, /* LCD Horizontal Display Width Register */ + {0x0034,0x03}, /* LCD Horizontal Non-Display Period Register */ + {0x0035,0x01}, /* TFT FPLINE Start Position Register */ + {0x0036,0x0B}, /* TFT FPLINE Pulse Width Register */ + {0x0038,0xEF}, /* LCD Vertical Display Height Register 0 */ + {0x0039,0x00}, /* LCD Vertical Display Height Register 1 */ + {0x003A,0x2C}, /* LCD Vertical Non-Display Period Register */ + {0x003B,0x0A}, /* TFT FPFRAME Start Position Register */ + {0x003C,0x01}, /* TFT FPFRAME Pulse Width Register */ + {0x0040,0x02}, /* LCD Display Mode Register */ + {0x0041,0x00}, /* LCD Miscellaneous Register */ + {0x0042,0x00}, /* LCD Display Start Address Register 0 */ + {0x0043,0x00}, /* LCD Display Start Address Register 1 */ + {0x0044,0x00}, /* LCD Display Start Address Register 2 */ + {0x0046,0x50}, /* LCD Memory Address Offset Register 0 */ + {0x0047,0x00}, /* LCD Memory Address Offset Register 1 */ + {0x0048,0x00}, /* LCD Pixel Panning Register */ + {0x004A,0x00}, /* LCD Display FIFO High Threshold Control Register */ + {0x004B,0x00}, /* LCD Display FIFO Low Threshold Control Register */ + {0x0050,0x4F}, /* CRT/TV Horizontal Display Width Register */ + {0x0052,0x13}, /* CRT/TV Horizontal Non-Display Period Register */ + {0x0053,0x01}, /* CRT/TV HRTC Start Position Register */ + {0x0054,0x0B}, /* CRT/TV HRTC Pulse Width Register */ + {0x0056,0xDF}, /* CRT/TV Vertical Display Height Register 0 */ + {0x0057,0x01}, /* CRT/TV Vertical Display Height Register 1 */ + {0x0058,0x2B}, /* CRT/TV Vertical Non-Display Period Register */ + {0x0059,0x09}, /* CRT/TV VRTC Start Position Register */ + {0x005A,0x01}, /* CRT/TV VRTC Pulse Width Register */ + {0x005B,0x10}, /* TV Output Control Register */ + {0x0060,0x03}, /* CRT/TV Display Mode Register */ + {0x0062,0x00}, /* CRT/TV Display Start Address Register 0 */ + {0x0063,0x00}, /* CRT/TV Display Start Address Register 1 */ + {0x0064,0x00}, /* CRT/TV Display Start Address Register 2 */ + {0x0066,0x40}, /* CRT/TV Memory Address Offset Register 0 */ + {0x0067,0x01}, /* CRT/TV Memory Address Offset Register 1 */ + {0x0068,0x00}, /* CRT/TV Pixel Panning Register */ + {0x006A,0x00}, /* CRT/TV Display FIFO High Threshold Control Register */ + {0x006B,0x00}, /* CRT/TV Display FIFO Low Threshold Control Register */ + {0x0070,0x00}, /* LCD Ink/Cursor Control Register */ + {0x0071,0x01}, /* LCD Ink/Cursor Start Address Register */ + {0x0072,0x00}, /* LCD Cursor X Position Register 0 */ + {0x0073,0x00}, /* LCD Cursor X Position Register 1 */ + {0x0074,0x00}, /* LCD Cursor Y Position Register 0 */ + {0x0075,0x00}, /* LCD Cursor Y Position Register 1 */ + {0x0076,0x00}, /* LCD Ink/Cursor Blue Color 0 Register */ + {0x0077,0x00}, /* LCD Ink/Cursor Green Color 0 Register */ + {0x0078,0x00}, /* LCD Ink/Cursor Red Color 0 Register */ + {0x007A,0x1F}, /* LCD Ink/Cursor Blue Color 1 Register */ + {0x007B,0x3F}, /* LCD Ink/Cursor Green Color 1 Register */ + {0x007C,0x1F}, /* LCD Ink/Cursor Red Color 1 Register */ + {0x007E,0x00}, /* LCD Ink/Cursor FIFO Threshold Register */ + {0x0080,0x00}, /* CRT/TV Ink/Cursor Control Register */ + {0x0081,0x01}, /* CRT/TV Ink/Cursor Start Address Register */ + {0x0082,0x00}, /* CRT/TV Cursor X Position Register 0 */ + {0x0083,0x00}, /* CRT/TV Cursor X Position Register 1 */ + {0x0084,0x00}, /* CRT/TV Cursor Y Position Register 0 */ + {0x0085,0x00}, /* CRT/TV Cursor Y Position Register 1 */ + {0x0086,0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register */ + {0x0087,0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register */ + {0x0088,0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register */ + {0x008A,0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register */ + {0x008B,0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register */ + {0x008C,0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register */ + {0x008E,0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register */ + {0x0100,0x00}, /* BitBlt Control Register 0 */ + {0x0101,0x00}, /* BitBlt Control Register 1 */ + {0x0102,0x00}, /* BitBlt ROP Code/Color Expansion Register */ + {0x0103,0x00}, /* BitBlt Operation Register */ + {0x0104,0x00}, /* BitBlt Source Start Address Register 0 */ + {0x0105,0x00}, /* BitBlt Source Start Address Register 1 */ + {0x0106,0x00}, /* BitBlt Source Start Address Register 2 */ + {0x0108,0x00}, /* BitBlt Destination Start Address Register 0 */ + {0x0109,0x00}, /* BitBlt Destination Start Address Register 1 */ + {0x010A,0x00}, /* BitBlt Destination Start Address Register 2 */ + {0x010C,0x00}, /* BitBlt Memory Address Offset Register 0 */ + {0x010D,0x00}, /* BitBlt Memory Address Offset Register 1 */ + {0x0110,0x00}, /* BitBlt Width Register 0 */ + {0x0111,0x00}, /* BitBlt Width Register 1 */ + {0x0112,0x00}, /* BitBlt Height Register 0 */ + {0x0113,0x00}, /* BitBlt Height Register 1 */ + {0x0114,0x00}, /* BitBlt Background Color Register 0 */ + {0x0115,0x00}, /* BitBlt Background Color Register 1 */ + {0x0118,0x00}, /* BitBlt Foreground Color Register 0 */ + {0x0119,0x00}, /* BitBlt Foreground Color Register 1 */ + {0x01E0,0x00}, /* Look-Up Table Mode Register */ + {0x01E2,0x00}, /* Look-Up Table Address Register */ + {0x01F0,0x10}, /* Power Save Configuration Register */ + {0x01F1,0x00}, /* Power Save Status Register */ + {0x01F4,0x00}, /* CPU-to-Memory Access Watchdog Timer Register */ + {0x01FC,0x01}, /* Display Mode Register */ +}; diff --git a/qemu/roms/u-boot/board/esd/common/s1d13806_640_480_16bpp.h b/qemu/roms/u-boot/board/esd/common/s1d13806_640_480_16bpp.h new file mode 100644 index 000000000..38fc1a7eb --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/s1d13806_640_480_16bpp.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * File generated by S1D13806CFG.EXE + * Panel: (active) 640x480 59Hz TFT Single 18-bit (PCLK=CLKI2=25.000MHz) + * Memory: Embedded SDRAM (MCLK=CLKI=49.152MHz) (BUSCLK=33.333MHz) + */ + +static S1D_REGS regs_13806_640_480_16bpp[] = +{ + {0x0001,0x00}, /* Miscellaneous Register */ + {0x01FC,0x00}, /* Display Mode Register */ + {0x0004,0x18}, /* General IO Pins Configuration Register 0 */ + {0x0005,0x00}, /* General IO Pins Configuration Register 1 */ + {0x0008,0x18}, /* General IO Pins Control Register 0 */ + {0x0009,0x00}, /* General IO Pins Control Register 1 */ + {0x0010,0x00}, /* Memory Clock Configuration Register */ + {0x0014,0x02}, /* LCD Pixel Clock Configuration Register */ + {0x0018,0x02}, /* CRT/TV Pixel Clock Configuration Register */ + {0x001C,0x02}, /* MediaPlug Clock Configuration Register */ + {0x001E,0x01}, /* CPU To Memory Wait State Select Register */ + {0x0021,0x03}, /* DRAM Refresh Rate Register */ + {0x002A,0x00}, /* DRAM Timings Control Register 0 */ + {0x002B,0x01}, /* DRAM Timings Control Register 1 */ + {0x0020,0x80}, /* Memory Configuration Register */ + {0x0030,0x25}, /* Panel Type Register */ + {0x0031,0x00}, /* MOD Rate Register */ + {0x0032,0x4F}, /* LCD Horizontal Display Width Register */ + {0x0034,0x13}, /* LCD Horizontal Non-Display Period Register */ + {0x0035,0x00}, /* TFT FPLINE Start Position Register */ + {0x0036,0x0B}, /* TFT FPLINE Pulse Width Register */ + {0x0038,0xDF}, /* LCD Vertical Display Height Register 0 */ + {0x0039,0x01}, /* LCD Vertical Display Height Register 1 */ + {0x003A,0x24}, /* LCD Vertical Non-Display Period Register */ + {0x003B,0x00}, /* TFT FPFRAME Start Position Register */ + {0x003C,0x01}, /* TFT FPFRAME Pulse Width Register */ + {0x0040,0x05}, /* LCD Display Mode Register */ + {0x0041,0x00}, /* LCD Miscellaneous Register */ + {0x0042,0x00}, /* LCD Display Start Address Register 0 */ + {0x0043,0x00}, /* LCD Display Start Address Register 1 */ + {0x0044,0x00}, /* LCD Display Start Address Register 2 */ + {0x0046,0x80}, /* LCD Memory Address Offset Register 0 */ + {0x0047,0x02}, /* LCD Memory Address Offset Register 1 */ + {0x0048,0x00}, /* LCD Pixel Panning Register */ + {0x004A,0x00}, /* LCD Display FIFO High Threshold Control Register */ + {0x004B,0x00}, /* LCD Display FIFO Low Threshold Control Register */ + {0x0050,0x4F}, /* CRT/TV Horizontal Display Width Register */ + {0x0052,0x13}, /* CRT/TV Horizontal Non-Display Period Register */ + {0x0053,0x01}, /* CRT/TV HRTC Start Position Register */ + {0x0054,0x0B}, /* CRT/TV HRTC Pulse Width Register */ + {0x0056,0xDF}, /* CRT/TV Vertical Display Height Register 0 */ + {0x0057,0x01}, /* CRT/TV Vertical Display Height Register 1 */ + {0x0058,0x2B}, /* CRT/TV Vertical Non-Display Period Register */ + {0x0059,0x09}, /* CRT/TV VRTC Start Position Register */ + {0x005A,0x01}, /* CRT/TV VRTC Pulse Width Register */ + {0x005B,0x10}, /* TV Output Control Register */ + {0x0060,0x05}, /* CRT/TV Display Mode Register */ + {0x0062,0x00}, /* CRT/TV Display Start Address Register 0 */ + {0x0063,0x00}, /* CRT/TV Display Start Address Register 1 */ + {0x0064,0x00}, /* CRT/TV Display Start Address Register 2 */ + {0x0066,0x80}, /* CRT/TV Memory Address Offset Register 0 */ + {0x0067,0x02}, /* CRT/TV Memory Address Offset Register 1 */ + {0x0068,0x00}, /* CRT/TV Pixel Panning Register */ + {0x006A,0x00}, /* CRT/TV Display FIFO High Threshold Control Register */ + {0x006B,0x00}, /* CRT/TV Display FIFO Low Threshold Control Register */ + {0x0070,0x00}, /* LCD Ink/Cursor Control Register */ + {0x0071,0x01}, /* LCD Ink/Cursor Start Address Register */ + {0x0072,0x00}, /* LCD Cursor X Position Register 0 */ + {0x0073,0x00}, /* LCD Cursor X Position Register 1 */ + {0x0074,0x00}, /* LCD Cursor Y Position Register 0 */ + {0x0075,0x00}, /* LCD Cursor Y Position Register 1 */ + {0x0076,0x00}, /* LCD Ink/Cursor Blue Color 0 Register */ + {0x0077,0x00}, /* LCD Ink/Cursor Green Color 0 Register */ + {0x0078,0x00}, /* LCD Ink/Cursor Red Color 0 Register */ + {0x007A,0x1F}, /* LCD Ink/Cursor Blue Color 1 Register */ + {0x007B,0x3F}, /* LCD Ink/Cursor Green Color 1 Register */ + {0x007C,0x1F}, /* LCD Ink/Cursor Red Color 1 Register */ + {0x007E,0x00}, /* LCD Ink/Cursor FIFO Threshold Register */ + {0x0080,0x00}, /* CRT/TV Ink/Cursor Control Register */ + {0x0081,0x01}, /* CRT/TV Ink/Cursor Start Address Register */ + {0x0082,0x00}, /* CRT/TV Cursor X Position Register 0 */ + {0x0083,0x00}, /* CRT/TV Cursor X Position Register 1 */ + {0x0084,0x00}, /* CRT/TV Cursor Y Position Register 0 */ + {0x0085,0x00}, /* CRT/TV Cursor Y Position Register 1 */ + {0x0086,0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register */ + {0x0087,0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register */ + {0x0088,0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register */ + {0x008A,0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register */ + {0x008B,0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register */ + {0x008C,0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register */ + {0x008E,0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register */ + {0x0100,0x00}, /* BitBlt Control Register 0 */ + {0x0101,0x00}, /* BitBlt Control Register 1 */ + {0x0102,0x00}, /* BitBlt ROP Code/Color Expansion Register */ + {0x0103,0x00}, /* BitBlt Operation Register */ + {0x0104,0x00}, /* BitBlt Source Start Address Register 0 */ + {0x0105,0x00}, /* BitBlt Source Start Address Register 1 */ + {0x0106,0x00}, /* BitBlt Source Start Address Register 2 */ + {0x0108,0x00}, /* BitBlt Destination Start Address Register 0 */ + {0x0109,0x00}, /* BitBlt Destination Start Address Register 1 */ + {0x010A,0x00}, /* BitBlt Destination Start Address Register 2 */ + {0x010C,0x00}, /* BitBlt Memory Address Offset Register 0 */ + {0x010D,0x00}, /* BitBlt Memory Address Offset Register 1 */ + {0x0110,0x00}, /* BitBlt Width Register 0 */ + {0x0111,0x00}, /* BitBlt Width Register 1 */ + {0x0112,0x00}, /* BitBlt Height Register 0 */ + {0x0113,0x00}, /* BitBlt Height Register 1 */ + {0x0114,0x00}, /* BitBlt Background Color Register 0 */ + {0x0115,0x00}, /* BitBlt Background Color Register 1 */ + {0x0118,0x00}, /* BitBlt Foreground Color Register 0 */ + {0x0119,0x00}, /* BitBlt Foreground Color Register 1 */ + {0x01E0,0x00}, /* Look-Up Table Mode Register */ + {0x01E2,0x00}, /* Look-Up Table Address Register */ + {0x01F0,0x10}, /* Power Save Configuration Register */ + {0x01F1,0x00}, /* Power Save Status Register */ + {0x01F4,0x00}, /* CPU-to-Memory Access Watchdog Timer Register */ + {0x01FC,0x01}, /* Display Mode Register */ +}; diff --git a/qemu/roms/u-boot/board/esd/common/xilinx_jtag/lenval.c b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/lenval.c new file mode 100644 index 000000000..5405efbc5 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/lenval.c @@ -0,0 +1,201 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/*******************************************************/ +/* file: lenval.c */ +/* abstract: This file contains routines for using */ +/* the lenVal data structure. */ +/*******************************************************/ + +#include <common.h> +#include <asm/processor.h> + +#include "lenval.h" +#include "ports.h" + + +/***************************************************************************** + * Function: value + * Description: Extract the long value from the lenval array. + * Parameters: plvValue - ptr to lenval. + * Returns: long - the extracted value. + *****************************************************************************/ +long value( lenVal* plvValue ) +{ + long lValue; /* result to hold the accumulated result */ + short sIndex; + + lValue = 0; + for ( sIndex = 0; sIndex < plvValue->len ; ++sIndex ) + { + lValue <<= 8; /* shift the accumulated result */ + lValue |= plvValue->val[ sIndex]; /* get the last byte first */ + } + + return( lValue ); +} + +/***************************************************************************** + * Function: initLenVal + * Description: Initialize the lenval array with the given value. + * Assumes lValue is less than 256. + * Parameters: plv - ptr to lenval. + * lValue - the value to set. + * Returns: void. + *****************************************************************************/ +void initLenVal( lenVal* plv, + long lValue ) +{ + plv->len = 1; + plv->val[0] = (unsigned char)lValue; +} + +/***************************************************************************** + * Function: EqualLenVal + * Description: Compare two lenval arrays with an optional mask. + * Parameters: plvTdoExpected - ptr to lenval #1. + * plvTdoCaptured - ptr to lenval #2. + * plvTdoMask - optional ptr to mask (=0 if no mask). + * Returns: short - 0 = mismatch; 1 = equal. + *****************************************************************************/ +short EqualLenVal( lenVal* plvTdoExpected, + lenVal* plvTdoCaptured, + lenVal* plvTdoMask ) +{ + short sEqual; + short sIndex; + unsigned char ucByteVal1; + unsigned char ucByteVal2; + unsigned char ucByteMask; + + sEqual = 1; + sIndex = plvTdoExpected->len; + + while ( sEqual && sIndex-- ) + { + ucByteVal1 = plvTdoExpected->val[ sIndex ]; + ucByteVal2 = plvTdoCaptured->val[ sIndex ]; + if ( plvTdoMask ) + { + ucByteMask = plvTdoMask->val[ sIndex ]; + ucByteVal1 &= ucByteMask; + ucByteVal2 &= ucByteMask; + } + if ( ucByteVal1 != ucByteVal2 ) + { + sEqual = 0; + } + } + + return( sEqual ); +} + + +/***************************************************************************** + * Function: RetBit + * Description: return the (byte, bit) of lv (reading from left to right). + * Parameters: plv - ptr to lenval. + * iByte - the byte to get the bit from. + * iBit - the bit number (0=msb) + * Returns: short - the bit value. + *****************************************************************************/ +short RetBit( lenVal* plv, + int iByte, + int iBit ) +{ + /* assert( ( iByte >= 0 ) && ( iByte < plv->len ) ); */ + /* assert( ( iBit >= 0 ) && ( iBit < 8 ) ); */ + return( (short)( ( plv->val[ iByte ] >> ( 7 - iBit ) ) & 0x1 ) ); +} + +/***************************************************************************** + * Function: SetBit + * Description: set the (byte, bit) of lv equal to val + * Example: SetBit("00000000",byte, 1) equals "01000000". + * Parameters: plv - ptr to lenval. + * iByte - the byte to get the bit from. + * iBit - the bit number (0=msb). + * sVal - the bit value to set. + * Returns: void. + *****************************************************************************/ +void SetBit( lenVal* plv, + int iByte, + int iBit, + short sVal ) +{ + unsigned char ucByteVal; + unsigned char ucBitMask; + + ucBitMask = (unsigned char)(1 << ( 7 - iBit )); + ucByteVal = (unsigned char)(plv->val[ iByte ] & (~ucBitMask)); + + if ( sVal ) + { + ucByteVal |= ucBitMask; + } + plv->val[ iByte ] = ucByteVal; +} + +/***************************************************************************** + * Function: AddVal + * Description: add val1 to val2 and store in resVal; + * assumes val1 and val2 are of equal length. + * Parameters: plvResVal - ptr to result. + * plvVal1 - ptr of addendum. + * plvVal2 - ptr of addendum. + * Returns: void. + *****************************************************************************/ +void addVal( lenVal* plvResVal, + lenVal* plvVal1, + lenVal* plvVal2 ) +{ + unsigned char ucCarry; + unsigned short usSum; + unsigned short usVal1; + unsigned short usVal2; + short sIndex; + + plvResVal->len = plvVal1->len; /* set up length of result */ + + /* start at least significant bit and add bytes */ + ucCarry = 0; + sIndex = plvVal1->len; + while ( sIndex-- ) + { + usVal1 = plvVal1->val[ sIndex ]; /* i'th byte of val1 */ + usVal2 = plvVal2->val[ sIndex ]; /* i'th byte of val2 */ + + /* add the two bytes plus carry from previous addition */ + usSum = (unsigned short)( usVal1 + usVal2 + ucCarry ); + + /* set up carry for next byte */ + ucCarry = (unsigned char)( ( usSum > 255 ) ? 1 : 0 ); + + /* set the i'th byte of the result */ + plvResVal->val[ sIndex ] = (unsigned char)usSum; + } +} + +/***************************************************************************** + * Function: readVal + * Description: read from XSVF numBytes bytes of data into x. + * Parameters: plv - ptr to lenval in which to put the bytes read. + * sNumBytes - the number of bytes to read. + * Returns: void. + *****************************************************************************/ +void readVal( lenVal* plv, + short sNumBytes ) +{ + unsigned char* pucVal; + + plv->len = sNumBytes; /* set the length of the lenVal */ + for ( pucVal = plv->val; sNumBytes; --sNumBytes, ++pucVal ) + { + /* read a byte of data into the lenVal */ + readByte( pucVal ); + } +} diff --git a/qemu/roms/u-boot/board/esd/common/xilinx_jtag/lenval.h b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/lenval.h new file mode 100644 index 000000000..3273eec44 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/lenval.h @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/*******************************************************/ +/* file: lenval.h */ +/* abstract: This file contains a description of the */ +/* data structure "lenval". */ +/*******************************************************/ + +#ifndef lenval_dot_h +#define lenval_dot_h + +/* the lenVal structure is a byte oriented type used to store an */ +/* arbitrary length binary value. As an example, the hex value */ +/* 0x0e3d is represented as a lenVal with len=2 (since 2 bytes */ +/* and val[0]=0e and val[1]=3d. val[2-MAX_LEN] are undefined */ + +/* maximum length (in bytes) of value to read in */ +/* this needs to be at least 4, and longer than the */ +/* length of the longest SDR instruction. If there is, */ +/* only 1 device in the chain, MAX_LEN must be at least */ +/* ceil(27/8) == 4. For 6 devices in a chain, MAX_LEN */ +/* must be 5, for 14 devices MAX_LEN must be 6, for 20 */ +/* devices MAX_LEN must be 7, etc.. */ +/* You can safely set MAX_LEN to a smaller number if you*/ +/* know how many devices will be in your chain. */ +#define MAX_LEN 7000 + + +typedef struct var_len_byte +{ + short len; /* number of chars in this value */ + unsigned char val[MAX_LEN+1]; /* bytes of data */ +} lenVal; + + +/* return the long representation of a lenVal */ +extern long value(lenVal *x); + +/* set lenVal equal to value */ +extern void initLenVal(lenVal *x, long value); + +/* check if expected equals actual (taking the mask into account) */ +extern short EqualLenVal(lenVal *expected, lenVal *actual, lenVal *mask); + +/* add val1+val2 and put the result in resVal */ +extern void addVal(lenVal *resVal, lenVal *val1, lenVal *val2); + +/* return the (byte, bit) of lv (reading from left to right) */ +extern short RetBit(lenVal *lv, int byte, int bit); + +/* set the (byte, bit) of lv equal to val (e.g. SetBit("00000000",byte, 1) + equals "01000000" */ +extern void SetBit(lenVal *lv, int byte, int bit, short val); + +/* read from XSVF numBytes bytes of data into x */ +extern void readVal(lenVal *x, short numBytes); + +#endif diff --git a/qemu/roms/u-boot/board/esd/common/xilinx_jtag/micro.c b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/micro.c new file mode 100644 index 000000000..556636c55 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/micro.c @@ -0,0 +1,1854 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/***************************************************************************** + * file: micro.c + * abstract: This file contains the function, xsvfExecute(), + * call for interpreting the XSVF commands. + * Usage: Call xsvfExecute() to process XSVF data. + * The XSVF data is retrieved by readByte() in ports.c + * Remove the main function if you already have one. + * Options: XSVF_SUPPORT_COMPRESSION + * This define supports the XC9500/XL compression scheme. + * This define adds support for XSDRINC and XSETSDRMASKS. + * XSVF_SUPPORT_ERRORCODES + * This define causes the xsvfExecute function to return + * an error code for specific errors. See error codes below. + * If this is not defined, the return value defaults to the + * legacy values for backward compatibility: + * 1 = success; 0 = failure. + * Debugging: DEBUG_MODE (Legacy name) + * Define DEBUG_MODE to compile with debugging features. + * Both micro.c and ports.c must be compiled with the DEBUG_MODE + * defined to enable the standalone main implementation in + * micro.c that reads XSVF from a file. + * History: v2.00 - Original XSVF implementation. + * v4.04 - Added delay at end of XSIR for XC18v00 support. + * Added new commands for CoolRunner support: + * XSTATE, XENDIR, XENDDR + * v4.05 - Cleanup micro.c but leave ports.c intact. + * v4.06 - Fix xsvfGotoTapState for retry transition. + * v4.07 - Update example waitTime implementations for + * compatibility with Virtex-II. + * v4.10 - Add new XSIR2 command that supports a 2-byte + * IR-length parameter for IR shifts > 255 bits. + * v4.11 - No change. Update version to match SVF2XSVF xlator. + * v4.14 - Added XCOMMENT. + * v5.00 - Improve XSTATE support. + * Added XWAIT. + *****************************************************************************/ + +#include <common.h> +#include <command.h> +#include <asm/processor.h> + +#include "micro.h" +#include "lenval.h" +#include "ports.h" + +const unsigned char *xsvfdata; + +/*============================================================================ + * XSVF #define + ============================================================================*/ + +#define XSVF_VERSION "5.00" + +/***************************************************************************** + * Define: XSVF_SUPPORT_COMPRESSION + * Description: Define this to support the XC9500/XL XSVF data compression + * scheme. + * Code size can be reduced by NOT supporting this feature. + * However, you must use the -nc (no compress) option when + * translating SVF to XSVF using the SVF2XSVF translator. + * Corresponding, uncompressed XSVF may be larger. + *****************************************************************************/ +#ifndef XSVF_SUPPORT_COMPRESSION +#define XSVF_SUPPORT_COMPRESSION 1 +#endif + +/***************************************************************************** + * Define: XSVF_SUPPORT_ERRORCODES + * Description: Define this to support the new XSVF error codes. + * (The original XSVF player just returned 1 for success and + * 0 for an unspecified failure.) + *****************************************************************************/ +#ifndef XSVF_SUPPORT_ERRORCODES +#define XSVF_SUPPORT_ERRORCODES 1 +#endif + +#ifdef XSVF_SUPPORT_ERRORCODES +#define XSVF_ERRORCODE(errorCode) errorCode +#else /* Use legacy error code */ +#define XSVF_ERRORCODE(errorCode) ((errorCode==XSVF_ERROR_NONE)?1:0) +#endif /* XSVF_SUPPORT_ERRORCODES */ + + +/*============================================================================ + * DEBUG_MODE #define + ============================================================================*/ +#define DEBUG_MODE + +#ifdef DEBUG_MODE +#define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat ); } +#define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat, arg1 ); } +#define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat, arg1, arg2 ); } +#define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + printf( pzFormat, arg1, arg2, arg3 ); } +#define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + xsvfPrintLenVal(plenVal); } +#else /* !DEBUG_MODE */ +#define XSVFDBG_PRINTF(iDebugLevel,pzFormat) +#define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) +#define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) +#define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) +#define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) +#endif /* DEBUG_MODE */ + + +/*============================================================================ + * XSVF Type Declarations + ============================================================================*/ + +/***************************************************************************** + * Struct: SXsvfInfo + * Description: This structure contains all of the data used during the + * execution of the XSVF. Some data is persistent, predefined + * information (e.g. lRunTestTime). The bulk of this struct's + * size is due to the lenVal structs (defined in lenval.h) + * which contain buffers for the active shift data. The MAX_LEN + * #define in lenval.h defines the size of these buffers. + * These buffers must be large enough to store the longest + * shift data in your XSVF file. For example: + * MAX_LEN >= ( longest_shift_data_in_bits / 8 ) + * Because the lenVal struct dominates the space usage of this + * struct, the rough size of this struct is: + * sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals) + * xsvfInitialize() contains initialization code for the data + * in this struct. + * xsvfCleanup() contains cleanup code for the data in this + * struct. + *****************************************************************************/ +typedef struct tagSXsvfInfo +{ + /* XSVF status information */ + unsigned char ucComplete; /* 0 = running; 1 = complete */ + unsigned char ucCommand; /* Current XSVF command byte */ + long lCommandCount; /* Number of commands processed */ + int iErrorCode; /* An error code. 0 = no error. */ + + /* TAP state/sequencing information */ + unsigned char ucTapState; /* Current TAP state */ + unsigned char ucEndIR; /* ENDIR TAP state (See SVF) */ + unsigned char ucEndDR; /* ENDDR TAP state (See SVF) */ + + /* RUNTEST information */ + unsigned char ucMaxRepeat; /* Max repeat loops (for xc9500/xl) */ + long lRunTestTime; /* Pre-specified RUNTEST time (usec) */ + + /* Shift Data Info and Buffers */ + long lShiftLengthBits; /* Len. current shift data in bits */ + short sShiftLengthBytes; /* Len. current shift data in bytes */ + + lenVal lvTdi; /* Current TDI shift data */ + lenVal lvTdoExpected; /* Expected TDO shift data */ + lenVal lvTdoCaptured; /* Captured TDO shift data */ + lenVal lvTdoMask; /* TDO mask: 0=dontcare; 1=compare */ + +#ifdef XSVF_SUPPORT_COMPRESSION + /* XSDRINC Data Buffers */ + lenVal lvAddressMask; /* Address mask for XSDRINC */ + lenVal lvDataMask; /* Data mask for XSDRINC */ + lenVal lvNextData; /* Next data for XSDRINC */ +#endif /* XSVF_SUPPORT_COMPRESSION */ +} SXsvfInfo; + +/* Declare pointer to functions that perform XSVF commands */ +typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* ); + +/*============================================================================ + * XSVF Command Bytes + ============================================================================*/ + +/* encodings of xsvf instructions */ +#define XCOMPLETE 0 +#define XTDOMASK 1 +#define XSIR 2 +#define XSDR 3 +#define XRUNTEST 4 +/* Reserved 5 */ +/* Reserved 6 */ +#define XREPEAT 7 +#define XSDRSIZE 8 +#define XSDRTDO 9 +#define XSETSDRMASKS 10 +#define XSDRINC 11 +#define XSDRB 12 +#define XSDRC 13 +#define XSDRE 14 +#define XSDRTDOB 15 +#define XSDRTDOC 16 +#define XSDRTDOE 17 +#define XSTATE 18 /* 4.00 */ +#define XENDIR 19 /* 4.04 */ +#define XENDDR 20 /* 4.04 */ +#define XSIR2 21 /* 4.10 */ +#define XCOMMENT 22 /* 4.14 */ +#define XWAIT 23 /* 5.00 */ +/* Insert new commands here */ +/* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */ +#define XLASTCMD 24 /* Last command marker */ + + +/*============================================================================ + * XSVF Command Parameter Values + ============================================================================*/ + +#define XSTATE_RESET 0 /* 4.00 parameter for XSTATE */ +#define XSTATE_RUNTEST 1 /* 4.00 parameter for XSTATE */ + +#define XENDXR_RUNTEST 0 /* 4.04 parameter for XENDIR/DR */ +#define XENDXR_PAUSE 1 /* 4.04 parameter for XENDIR/DR */ + +/* TAP states */ +#define XTAPSTATE_RESET 0x00 +#define XTAPSTATE_RUNTEST 0x01 /* a.k.a. IDLE */ +#define XTAPSTATE_SELECTDR 0x02 +#define XTAPSTATE_CAPTUREDR 0x03 +#define XTAPSTATE_SHIFTDR 0x04 +#define XTAPSTATE_EXIT1DR 0x05 +#define XTAPSTATE_PAUSEDR 0x06 +#define XTAPSTATE_EXIT2DR 0x07 +#define XTAPSTATE_UPDATEDR 0x08 +#define XTAPSTATE_IRSTATES 0x09 /* All IR states begin here */ +#define XTAPSTATE_SELECTIR 0x09 +#define XTAPSTATE_CAPTUREIR 0x0A +#define XTAPSTATE_SHIFTIR 0x0B +#define XTAPSTATE_EXIT1IR 0x0C +#define XTAPSTATE_PAUSEIR 0x0D +#define XTAPSTATE_EXIT2IR 0x0E +#define XTAPSTATE_UPDATEIR 0x0F + +/*============================================================================ + * XSVF Function Prototypes + ============================================================================*/ + +int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ); /* Illegal command function */ +int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSIR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo ); +int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo ); +int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo ); +/* Insert new command functions here */ + +/*============================================================================ + * XSVF Global Variables + ============================================================================*/ + +/* Array of XSVF command functions. Must follow command byte value order! */ +/* If your compiler cannot take this form, then convert to a switch statement*/ +TXsvfDoCmdFuncPtr xsvf_pfDoCmd[] = +{ + xsvfDoXCOMPLETE, /* 0 */ + xsvfDoXTDOMASK, /* 1 */ + xsvfDoXSIR, /* 2 */ + xsvfDoXSDR, /* 3 */ + xsvfDoXRUNTEST, /* 4 */ + xsvfDoIllegalCmd, /* 5 */ + xsvfDoIllegalCmd, /* 6 */ + xsvfDoXREPEAT, /* 7 */ + xsvfDoXSDRSIZE, /* 8 */ + xsvfDoXSDRTDO, /* 9 */ +#ifdef XSVF_SUPPORT_COMPRESSION + xsvfDoXSETSDRMASKS, /* 10 */ + xsvfDoXSDRINC, /* 11 */ +#else + xsvfDoIllegalCmd, /* 10 */ + xsvfDoIllegalCmd, /* 11 */ +#endif /* XSVF_SUPPORT_COMPRESSION */ + xsvfDoXSDRBCE, /* 12 */ + xsvfDoXSDRBCE, /* 13 */ + xsvfDoXSDRBCE, /* 14 */ + xsvfDoXSDRTDOBCE, /* 15 */ + xsvfDoXSDRTDOBCE, /* 16 */ + xsvfDoXSDRTDOBCE, /* 17 */ + xsvfDoXSTATE, /* 18 */ + xsvfDoXENDXR, /* 19 */ + xsvfDoXENDXR, /* 20 */ + xsvfDoXSIR2, /* 21 */ + xsvfDoXCOMMENT, /* 22 */ + xsvfDoXWAIT /* 23 */ +/* Insert new command functions here */ +}; + +#ifdef DEBUG_MODE +char* xsvf_pzCommandName[] = +{ + "XCOMPLETE", + "XTDOMASK", + "XSIR", + "XSDR", + "XRUNTEST", + "Reserved5", + "Reserved6", + "XREPEAT", + "XSDRSIZE", + "XSDRTDO", + "XSETSDRMASKS", + "XSDRINC", + "XSDRB", + "XSDRC", + "XSDRE", + "XSDRTDOB", + "XSDRTDOC", + "XSDRTDOE", + "XSTATE", + "XENDIR", + "XENDDR", + "XSIR2", + "XCOMMENT", + "XWAIT" +}; + +char* xsvf_pzErrorName[] = +{ + "No error", + "ERROR: Unknown", + "ERROR: TDO mismatch", + "ERROR: TDO mismatch and exceeded max retries", + "ERROR: Unsupported XSVF command", + "ERROR: Illegal state specification", + "ERROR: Data overflows allocated MAX_LEN buffer size" +}; + +char* xsvf_pzTapState[] = +{ + "RESET", /* 0x00 */ + "RUNTEST/IDLE", /* 0x01 */ + "DRSELECT", /* 0x02 */ + "DRCAPTURE", /* 0x03 */ + "DRSHIFT", /* 0x04 */ + "DREXIT1", /* 0x05 */ + "DRPAUSE", /* 0x06 */ + "DREXIT2", /* 0x07 */ + "DRUPDATE", /* 0x08 */ + "IRSELECT", /* 0x09 */ + "IRCAPTURE", /* 0x0A */ + "IRSHIFT", /* 0x0B */ + "IREXIT1", /* 0x0C */ + "IRPAUSE", /* 0x0D */ + "IREXIT2", /* 0x0E */ + "IRUPDATE" /* 0x0F */ +}; +#endif /* DEBUG_MODE */ + +/*#ifdef DEBUG_MODE */ +/* FILE* in; /XXX* Legacy DEBUG_MODE file pointer */ +int xsvf_iDebugLevel; +/*#endif /XXX* DEBUG_MODE */ + +/*============================================================================ + * Utility Functions + ============================================================================*/ + +/***************************************************************************** + * Function: xsvfPrintLenVal + * Description: Print the lenval value in hex. + * Parameters: plv - ptr to lenval. + * Returns: void. + *****************************************************************************/ +#ifdef DEBUG_MODE +void xsvfPrintLenVal( lenVal *plv ) +{ + int i; + + if ( plv ) + { + printf( "0x" ); + for ( i = 0; i < plv->len; ++i ) + { + printf( "%02x", ((unsigned int)(plv->val[ i ])) ); + } + } +} +#endif /* DEBUG_MODE */ + + +/***************************************************************************** + * Function: xsvfInfoInit + * Description: Initialize the xsvfInfo data. + * Parameters: pXsvfInfo - ptr to the XSVF info structure. + * Returns: int - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfInfoInit( SXsvfInfo* pXsvfInfo ) +{ + XSVFDBG_PRINTF1( 4, " sizeof( SXsvfInfo ) = %d bytes\n", + sizeof( SXsvfInfo ) ); + + pXsvfInfo->ucComplete = 0; + pXsvfInfo->ucCommand = XCOMPLETE; + pXsvfInfo->lCommandCount = 0; + pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; + pXsvfInfo->ucMaxRepeat = 0; + pXsvfInfo->ucTapState = XTAPSTATE_RESET; + pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST; + pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST; + pXsvfInfo->lShiftLengthBits = 0L; + pXsvfInfo->sShiftLengthBytes= 0; + pXsvfInfo->lRunTestTime = 0L; + + return( 0 ); +} + +/***************************************************************************** + * Function: xsvfInfoCleanup + * Description: Cleanup the xsvfInfo data. + * Parameters: pXsvfInfo - ptr to the XSVF info structure. + * Returns: void. + *****************************************************************************/ +void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo ) +{ +} + +/***************************************************************************** + * Function: xsvfGetAsNumBytes + * Description: Calculate the number of bytes the given number of bits + * consumes. + * Parameters: lNumBits - the number of bits. + * Returns: short - the number of bytes to store the number of bits. + *****************************************************************************/ +short xsvfGetAsNumBytes( long lNumBits ) +{ + return( (short)( ( lNumBits + 7L ) / 8L ) ); +} + +/***************************************************************************** + * Function: xsvfTmsTransition + * Description: Apply TMS and transition TAP controller by applying one TCK + * cycle. + * Parameters: sTms - new TMS value. + * Returns: void. + *****************************************************************************/ +void xsvfTmsTransition( short sTms ) +{ + setPort( TMS, sTms ); + setPort( TCK, 0 ); + setPort( TCK, 1 ); +} + +/***************************************************************************** + * Function: xsvfGotoTapState + * Description: From the current TAP state, go to the named TAP state. + * A target state of RESET ALWAYS causes TMS reset sequence. + * All SVF standard stable state paths are supported. + * All state transitions are supported except for the following + * which cause an XSVF_ERROR_ILLEGALSTATE: + * - Target==DREXIT2; Start!=DRPAUSE + * - Target==IREXIT2; Start!=IRPAUSE + * Parameters: pucTapState - Current TAP state; returns final TAP state. + * ucTargetState - New target TAP state. + * Returns: int - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfGotoTapState( unsigned char* pucTapState, + unsigned char ucTargetState ) +{ + int i; + int iErrorCode; + + iErrorCode = XSVF_ERROR_NONE; + if ( ucTargetState == XTAPSTATE_RESET ) + { + /* If RESET, always perform TMS reset sequence to reset/sync TAPs */ + xsvfTmsTransition( 1 ); + for ( i = 0; i < 5; ++i ) + { + setPort( TCK, 0 ); + setPort( TCK, 1 ); + } + *pucTapState = XTAPSTATE_RESET; + XSVFDBG_PRINTF( 3, " TMS Reset Sequence -> Test-Logic-Reset\n" ); + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } else if ( ( ucTargetState != *pucTapState ) && + ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) || + ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) ) + { + /* Trap illegal TAP state path specification */ + iErrorCode = XSVF_ERROR_ILLEGALSTATE; + } else { + if ( ucTargetState == *pucTapState ) + { + /* Already in target state. Do nothing except when in DRPAUSE + or in IRPAUSE to comply with SVF standard */ + if ( ucTargetState == XTAPSTATE_PAUSEDR ) + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2DR; + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + else if ( ucTargetState == XTAPSTATE_PAUSEIR ) + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2IR; + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + } + + /* Perform TAP state transitions to get to the target state */ + while ( ucTargetState != *pucTapState ) + { + switch ( *pucTapState ) + { + case XTAPSTATE_RESET: + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_RUNTEST; + break; + case XTAPSTATE_RUNTEST: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTDR; + break; + case XTAPSTATE_SELECTDR: + if ( ucTargetState >= XTAPSTATE_IRSTATES ) + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTIR; + } + else + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_CAPTUREDR; + } + break; + case XTAPSTATE_CAPTUREDR: + if ( ucTargetState == XTAPSTATE_SHIFTDR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTDR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1DR; + } + break; + case XTAPSTATE_SHIFTDR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1DR; + break; + case XTAPSTATE_EXIT1DR: + if ( ucTargetState == XTAPSTATE_PAUSEDR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_PAUSEDR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEDR; + } + break; + case XTAPSTATE_PAUSEDR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2DR; + break; + case XTAPSTATE_EXIT2DR: + if ( ucTargetState == XTAPSTATE_SHIFTDR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTDR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEDR; + } + break; + case XTAPSTATE_UPDATEDR: + if ( ucTargetState == XTAPSTATE_RUNTEST ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_RUNTEST; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTDR; + } + break; + case XTAPSTATE_SELECTIR: + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_CAPTUREIR; + break; + case XTAPSTATE_CAPTUREIR: + if ( ucTargetState == XTAPSTATE_SHIFTIR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTIR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1IR; + } + break; + case XTAPSTATE_SHIFTIR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT1IR; + break; + case XTAPSTATE_EXIT1IR: + if ( ucTargetState == XTAPSTATE_PAUSEIR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_PAUSEIR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEIR; + } + break; + case XTAPSTATE_PAUSEIR: + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_EXIT2IR; + break; + case XTAPSTATE_EXIT2IR: + if ( ucTargetState == XTAPSTATE_SHIFTIR ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_SHIFTIR; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_UPDATEIR; + } + break; + case XTAPSTATE_UPDATEIR: + if ( ucTargetState == XTAPSTATE_RUNTEST ) + { + xsvfTmsTransition( 0 ); + *pucTapState = XTAPSTATE_RUNTEST; + } + else + { + xsvfTmsTransition( 1 ); + *pucTapState = XTAPSTATE_SELECTDR; + } + break; + default: + iErrorCode = XSVF_ERROR_ILLEGALSTATE; + *pucTapState = ucTargetState; /* Exit while loop */ + break; + } + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + } + } + + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfShiftOnly + * Description: Assumes that starting TAP state is SHIFT-DR or SHIFT-IR. + * Shift the given TDI data into the JTAG scan chain. + * Optionally, save the TDO data shifted out of the scan chain. + * Last shift cycle is special: capture last TDO, set last TDI, + * but does not pulse TCK. Caller must pulse TCK and optionally + * set TMS=1 to exit shift state. + * Parameters: lNumBits - number of bits to shift. + * plvTdi - ptr to lenval for TDI data. + * plvTdoCaptured - ptr to lenval for storing captured TDO data. + * iExitShift - 1=exit at end of shift; 0=stay in Shift-DR. + * Returns: void. + *****************************************************************************/ +void xsvfShiftOnly( long lNumBits, + lenVal* plvTdi, + lenVal* plvTdoCaptured, + int iExitShift ) +{ + unsigned char* pucTdi; + unsigned char* pucTdo; + unsigned char ucTdiByte; + unsigned char ucTdoByte; + unsigned char ucTdoBit; + int i; + + /* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */ + + /* Initialize TDO storage len == TDI len */ + pucTdo = 0; + if ( plvTdoCaptured ) + { + plvTdoCaptured->len = plvTdi->len; + pucTdo = plvTdoCaptured->val + plvTdi->len; + } + + /* Shift LSB first. val[N-1] == LSB. val[0] == MSB. */ + pucTdi = plvTdi->val + plvTdi->len; + while ( lNumBits ) + { + /* Process on a byte-basis */ + ucTdiByte = (*(--pucTdi)); + ucTdoByte = 0; + for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i ) + { + --lNumBits; + if ( iExitShift && !lNumBits ) + { + /* Exit Shift-DR state */ + setPort( TMS, 1 ); + } + + /* Set the new TDI value */ + setPort( TDI, (short)(ucTdiByte & 1) ); + ucTdiByte >>= 1; + + /* Set TCK low */ + setPort( TCK, 0 ); + + if ( pucTdo ) + { + /* Save the TDO value */ + ucTdoBit = readTDOBit(); + ucTdoByte |= ( ucTdoBit << i ); + } + + /* Set TCK high */ + setPort( TCK, 1 ); + } + + /* Save the TDO byte value */ + if ( pucTdo ) + { + (*(--pucTdo)) = ucTdoByte; + } + } +} + +/***************************************************************************** + * Function: xsvfShift + * Description: Goes to the given starting TAP state. + * Calls xsvfShiftOnly to shift in the given TDI data and + * optionally capture the TDO data. + * Compares the TDO captured data against the TDO expected + * data. + * If a data mismatch occurs, then executes the exception + * handling loop upto ucMaxRepeat times. + * Parameters: pucTapState - Ptr to current TAP state. + * ucStartState - Starting shift state: Shift-DR or Shift-IR. + * lNumBits - number of bits to shift. + * plvTdi - ptr to lenval for TDI data. + * plvTdoCaptured - ptr to lenval for storing TDO data. + * plvTdoExpected - ptr to expected TDO data. + * plvTdoMask - ptr to TDO mask. + * ucEndState - state in which to end the shift. + * lRunTestTime - amount of time to wait after the shift. + * ucMaxRepeat - Maximum number of retries on TDO mismatch. + * Returns: int - 0 = success; otherwise TDO mismatch. + * Notes: XC9500XL-only Optimization: + * Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1] + * is NOT all zeros and sMatch==1. + *****************************************************************************/ +int xsvfShift( unsigned char* pucTapState, + unsigned char ucStartState, + long lNumBits, + lenVal* plvTdi, + lenVal* plvTdoCaptured, + lenVal* plvTdoExpected, + lenVal* plvTdoMask, + unsigned char ucEndState, + long lRunTestTime, + unsigned char ucMaxRepeat ) +{ + int iErrorCode; + int iMismatch; + unsigned char ucRepeat; + int iExitShift; + + iErrorCode = XSVF_ERROR_NONE; + iMismatch = 0; + ucRepeat = 0; + iExitShift = ( ucStartState != ucEndState ); + + XSVFDBG_PRINTF1( 3, " Shift Length = %ld\n", lNumBits ); + XSVFDBG_PRINTF( 4, " TDI = "); + XSVFDBG_PRINTLENVAL( 4, plvTdi ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF( 4, " TDO Expected = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoExpected ); + XSVFDBG_PRINTF( 4, "\n"); + + if ( !lNumBits ) + { + /* Compatibility with XSVF2.00: XSDR 0 = no shift, but wait in RTI */ + if ( lRunTestTime ) + { + /* Wait for prespecified XRUNTEST time */ + xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST ); + XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime ); + waitTime( lRunTestTime ); + } + } + else + { + do + { + /* Goto Shift-DR or Shift-IR */ + xsvfGotoTapState( pucTapState, ucStartState ); + + /* Shift TDI and capture TDO */ + xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift ); + + if ( plvTdoExpected ) + { + /* Compare TDO data to expected TDO data */ + iMismatch = !EqualLenVal( plvTdoExpected, + plvTdoCaptured, + plvTdoMask ); + } + + if ( iExitShift ) + { + /* Update TAP state: Shift->Exit */ + ++(*pucTapState); + XSVFDBG_PRINTF1( 3, " TAP State = %s\n", + xsvf_pzTapState[ *pucTapState ] ); + + if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) ) + { + XSVFDBG_PRINTF( 4, " TDO Expected = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoExpected ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF( 4, " TDO Captured = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF( 4, " TDO Mask = "); + XSVFDBG_PRINTLENVAL( 4, plvTdoMask ); + XSVFDBG_PRINTF( 4, "\n"); + XSVFDBG_PRINTF1( 3, " Retry #%d\n", ( ucRepeat + 1 ) ); + /* Do exception handling retry - ShiftDR only */ + xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR ); + /* Shift 1 extra bit */ + xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR ); + /* Increment RUNTEST time by an additional 25% */ + lRunTestTime += ( lRunTestTime >> 2 ); + } + else + { + /* Do normal exit from Shift-XR */ + xsvfGotoTapState( pucTapState, ucEndState ); + } + + if ( lRunTestTime ) + { + /* Wait for prespecified XRUNTEST time */ + xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST ); + XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime ); + waitTime( lRunTestTime ); + } + } + } while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) ); + } + + if ( iMismatch ) + { + XSVFDBG_PRINTF( 1, " TDO Expected = "); + XSVFDBG_PRINTLENVAL( 1, plvTdoExpected ); + XSVFDBG_PRINTF( 1, "\n"); + XSVFDBG_PRINTF( 1, " TDO Captured = "); + XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured ); + XSVFDBG_PRINTF( 1, "\n"); + XSVFDBG_PRINTF( 1, " TDO Mask = "); + XSVFDBG_PRINTLENVAL( 1, plvTdoMask ); + XSVFDBG_PRINTF( 1, "\n"); + if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) ) + { + iErrorCode = XSVF_ERROR_MAXRETRIES; + } + else + { + iErrorCode = XSVF_ERROR_TDOMISMATCH; + } + } + + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfBasicXSDRTDO + * Description: Get the XSDRTDO parameters and execute the XSDRTDO command. + * This is the common function for all XSDRTDO commands. + * Parameters: pucTapState - Current TAP state. + * lShiftLengthBits - number of bits to shift. + * sShiftLengthBytes - number of bytes to read. + * plvTdi - ptr to lenval for TDI data. + * lvTdoCaptured - ptr to lenval for storing TDO data. + * iEndState - state in which to end the shift. + * lRunTestTime - amount of time to wait after the shift. + * ucMaxRepeat - maximum xc9500/xl retries. + * Returns: int - 0 = success; otherwise TDO mismatch. + *****************************************************************************/ +int xsvfBasicXSDRTDO( unsigned char* pucTapState, + long lShiftLengthBits, + short sShiftLengthBytes, + lenVal* plvTdi, + lenVal* plvTdoCaptured, + lenVal* plvTdoExpected, + lenVal* plvTdoMask, + unsigned char ucEndState, + long lRunTestTime, + unsigned char ucMaxRepeat ) +{ + readVal( plvTdi, sShiftLengthBytes ); + if ( plvTdoExpected ) + { + readVal( plvTdoExpected, sShiftLengthBytes ); + } + return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits, + plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask, + ucEndState, lRunTestTime, ucMaxRepeat ) ); +} + +/***************************************************************************** + * Function: xsvfDoSDRMasking + * Description: Update the data value with the next XSDRINC data and address. + * Example: dataVal=0x01ff, nextData=0xab, addressMask=0x0100, + * dataMask=0x00ff, should set dataVal to 0x02ab + * Parameters: plvTdi - The current TDI value. + * plvNextData - the next data value. + * plvAddressMask - the address mask. + * plvDataMask - the data mask. + * Returns: void. + *****************************************************************************/ +#ifdef XSVF_SUPPORT_COMPRESSION +void xsvfDoSDRMasking( lenVal* plvTdi, + lenVal* plvNextData, + lenVal* plvAddressMask, + lenVal* plvDataMask ) +{ + int i; + unsigned char ucTdi; + unsigned char ucTdiMask; + unsigned char ucDataMask; + unsigned char ucNextData; + unsigned char ucNextMask; + short sNextData; + + /* add the address Mask to dataVal and return as a new dataVal */ + addVal( plvTdi, plvTdi, plvAddressMask ); + + ucNextData = 0; + ucNextMask = 0; + sNextData = plvNextData->len; + for ( i = plvDataMask->len - 1; i >= 0; --i ) + { + /* Go through data mask in reverse order looking for mask (1) bits */ + ucDataMask = plvDataMask->val[ i ]; + if ( ucDataMask ) + { + /* Retrieve the corresponding TDI byte value */ + ucTdi = plvTdi->val[ i ]; + + /* For each bit in the data mask byte, look for 1's */ + ucTdiMask = 1; + while ( ucDataMask ) + { + if ( ucDataMask & 1 ) + { + if ( !ucNextMask ) + { + /* Get the next data byte */ + ucNextData = plvNextData->val[ --sNextData ]; + ucNextMask = 1; + } + + /* Set or clear the data bit according to the next data */ + if ( ucNextData & ucNextMask ) + { + ucTdi |= ucTdiMask; /* Set bit */ + } + else + { + ucTdi &= ( ~ucTdiMask ); /* Clear bit */ + } + + /* Update the next data */ + ucNextMask <<= 1; + } + ucTdiMask <<= 1; + ucDataMask >>= 1; + } + + /* Update the TDI value */ + plvTdi->val[ i ] = ucTdi; + } + } +} +#endif /* XSVF_SUPPORT_COMPRESSION */ + +/*============================================================================ + * XSVF Command Functions (type = TXsvfDoCmdFuncPtr) + * These functions update pXsvfInfo->iErrorCode only on an error. + * Otherwise, the error code is left alone. + * The function returns the error code from the function. + ============================================================================*/ + +/***************************************************************************** + * Function: xsvfDoIllegalCmd + * Description: Function place holder for illegal/unsupported commands. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ) +{ + XSVFDBG_PRINTF2( 0, "ERROR: Encountered unsupported command #%d (%s)\n", + ((unsigned int)(pXsvfInfo->ucCommand)), + ((pXsvfInfo->ucCommand < XLASTCMD) + ? (xsvf_pzCommandName[pXsvfInfo->ucCommand]) + : "Unknown") ); + pXsvfInfo->iErrorCode = XSVF_ERROR_ILLEGALCMD; + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXCOMPLETE + * Description: XCOMPLETE (no parameters) + * Update complete status for XSVF player. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo ) +{ + pXsvfInfo->ucComplete = 1; + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function: xsvfDoXTDOMASK + * Description: XTDOMASK <lenVal.TdoMask[XSDRSIZE]> + * Prespecify the TDO compare mask. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo ) +{ + readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes ); + XSVFDBG_PRINTF( 4, " TDO Mask = "); + XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) ); + XSVFDBG_PRINTF( 4, "\n"); + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function: xsvfDoXSIR + * Description: XSIR <(byte)shiftlen> <lenVal.TDI[shiftlen]> + * Get the instruction and shift the instruction into the TAP. + * If prespecified XRUNTEST!=0, goto RUNTEST and wait after + * the shift for XRUNTEST usec. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSIR( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucShiftIrBits; + short sShiftIrBytes; + int iErrorCode; + + /* Get the shift length and store */ + readByte( &ucShiftIrBits ); + sShiftIrBytes = xsvfGetAsNumBytes( ucShiftIrBits ); + XSVFDBG_PRINTF1( 3, " XSIR length = %d\n", + ((unsigned int)ucShiftIrBits) ); + + if ( sShiftIrBytes > MAX_LEN ) + { + iErrorCode = XSVF_ERROR_DATAOVERFLOW; + } + else + { + /* Get and store instruction to shift in */ + readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) ); + + /* Shift the data */ + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR, + ucShiftIrBits, &(pXsvfInfo->lvTdi), + /*plvTdoCaptured*/0, /*plvTdoExpected*/0, + /*plvTdoMask*/0, pXsvfInfo->ucEndIR, + pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 ); + } + + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXSIR2 + * Description: XSIR <(2-byte)shiftlen> <lenVal.TDI[shiftlen]> + * Get the instruction and shift the instruction into the TAP. + * If prespecified XRUNTEST!=0, goto RUNTEST and wait after + * the shift for XRUNTEST usec. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo ) +{ + long lShiftIrBits; + short sShiftIrBytes; + int iErrorCode; + + /* Get the shift length and store */ + readVal( &(pXsvfInfo->lvTdi), 2 ); + lShiftIrBits = value( &(pXsvfInfo->lvTdi) ); + sShiftIrBytes = xsvfGetAsNumBytes( lShiftIrBits ); + XSVFDBG_PRINTF1( 3, " XSIR2 length = %d\n", (int)lShiftIrBits); + + if ( sShiftIrBytes > MAX_LEN ) + { + iErrorCode = XSVF_ERROR_DATAOVERFLOW; + } + else + { + /* Get and store instruction to shift in */ + readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) ); + + /* Shift the data */ + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR, + lShiftIrBits, &(pXsvfInfo->lvTdi), + /*plvTdoCaptured*/0, /*plvTdoExpected*/0, + /*plvTdoMask*/0, pXsvfInfo->ucEndIR, + pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 ); + } + + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXSDR + * Description: XSDR <lenVal.TDI[XSDRSIZE]> + * Shift the given TDI data into the JTAG scan chain. + * Compare the captured TDO with the expected TDO from the + * previous XSDRTDO command using the previously specified + * XTDOMASK. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSDR( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes ); + /* use TDOExpected from last XSDRTDO instruction */ + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR, + pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXRUNTEST + * Description: XRUNTEST <uint32> + * Prespecify the XRUNTEST wait time for shift operations. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo ) +{ + readVal( &(pXsvfInfo->lvTdi), 4 ); + pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) ); + XSVFDBG_PRINTF1( 3, " XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime ); + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function: xsvfDoXREPEAT + * Description: XREPEAT <byte> + * Prespecify the maximum number of XC9500/XL retries. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo ) +{ + readByte( &(pXsvfInfo->ucMaxRepeat) ); + XSVFDBG_PRINTF1( 3, " XREPEAT = %d\n", + ((unsigned int)(pXsvfInfo->ucMaxRepeat)) ); + return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function: xsvfDoXSDRSIZE + * Description: XSDRSIZE <uint32> + * Prespecify the XRUNTEST wait time for shift operations. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + iErrorCode = XSVF_ERROR_NONE; + readVal( &(pXsvfInfo->lvTdi), 4 ); + pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) ); + pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits ); + XSVFDBG_PRINTF1( 3, " XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits ); + if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN ) + { + iErrorCode = XSVF_ERROR_DATAOVERFLOW; + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXSDRTDO + * Description: XSDRTDO <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]> + * Get the TDI and expected TDO values. Then, shift. + * Compare the expected TDO with the captured TDO using the + * prespecified XTDOMASK. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), + pXsvfInfo->lShiftLengthBits, + pXsvfInfo->sShiftLengthBytes, + &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), + pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, + pXsvfInfo->ucMaxRepeat ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXSETSDRMASKS + * Description: XSETSDRMASKS <lenVal.AddressMask[XSDRSIZE]> + * <lenVal.DataMask[XSDRSIZE]> + * Get the prespecified address and data mask for the XSDRINC + * command. + * Used for xc9500/xl compressed XSVF data. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +#ifdef XSVF_SUPPORT_COMPRESSION +int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo ) +{ + /* read the addressMask */ + readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes ); + /* read the dataMask */ + readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes ); + + XSVFDBG_PRINTF( 4, " Address Mask = " ); + XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) ); + XSVFDBG_PRINTF( 4, "\n" ); + XSVFDBG_PRINTF( 4, " Data Mask = " ); + XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) ); + XSVFDBG_PRINTF( 4, "\n" ); + + return( XSVF_ERROR_NONE ); +} +#endif /* XSVF_SUPPORT_COMPRESSION */ + +/***************************************************************************** + * Function: xsvfDoXSDRINC + * Description: XSDRINC <lenVal.firstTDI[XSDRSIZE]> <byte(numTimes)> + * <lenVal.data[XSETSDRMASKS.dataMask.len]> ... + * Get the XSDRINC parameters and execute the XSDRINC command. + * XSDRINC starts by loading the first TDI shift value. + * Then, for numTimes, XSDRINC gets the next piece of data, + * replaces the bits from the starting TDI as defined by the + * XSETSDRMASKS.dataMask, adds the address mask from + * XSETSDRMASKS.addressMask, shifts the new TDI value, + * and compares the TDO to the expected TDO from the previous + * XSDRTDO command using the XTDOMASK. + * Used for xc9500/xl compressed XSVF data. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +#ifdef XSVF_SUPPORT_COMPRESSION +int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + int iDataMaskLen; + unsigned char ucDataMask; + unsigned char ucNumTimes; + unsigned char i; + + readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes ); + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR, + pXsvfInfo->lShiftLengthBits, + &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat ); + if ( !iErrorCode ) + { + /* Calculate number of data mask bits */ + iDataMaskLen = 0; + for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i ) + { + ucDataMask = pXsvfInfo->lvDataMask.val[ i ]; + while ( ucDataMask ) + { + iDataMaskLen += ( ucDataMask & 1 ); + ucDataMask >>= 1; + } + } + + /* Get the number of data pieces, i.e. number of times to shift */ + readByte( &ucNumTimes ); + + /* For numTimes, get data, fix TDI, and shift */ + for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i ) + { + readVal( &(pXsvfInfo->lvNextData), + xsvfGetAsNumBytes( iDataMaskLen ) ); + xsvfDoSDRMasking( &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvNextData), + &(pXsvfInfo->lvAddressMask), + &(pXsvfInfo->lvDataMask) ); + iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), + XTAPSTATE_SHIFTDR, + pXsvfInfo->lShiftLengthBits, + &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + &(pXsvfInfo->lvTdoMask), + pXsvfInfo->ucEndDR, + pXsvfInfo->lRunTestTime, + pXsvfInfo->ucMaxRepeat ); + } + } + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} +#endif /* XSVF_SUPPORT_COMPRESSION */ + +/***************************************************************************** + * Function: xsvfDoXSDRBCE + * Description: XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> + * If not already in SHIFTDR, goto SHIFTDR. + * Shift the given TDI data into the JTAG scan chain. + * Ignore TDO. + * If cmd==XSDRE, then goto ENDDR. Otherwise, stay in ShiftDR. + * XSDRB, XSDRC, and XSDRE are the same implementation. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucEndDR; + int iErrorCode; + ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ? + pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR); + iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), + pXsvfInfo->lShiftLengthBits, + pXsvfInfo->sShiftLengthBytes, + &(pXsvfInfo->lvTdi), + /*plvTdoCaptured*/0, /*plvTdoExpected*/0, + /*plvTdoMask*/0, ucEndDR, + /*lRunTestTime*/0, /*ucMaxRepeat*/0 ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXSDRTDOBCE + * Description: XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]> + * If not already in SHIFTDR, goto SHIFTDR. + * Shift the given TDI data into the JTAG scan chain. + * Compare TDO, but do NOT use XTDOMASK. + * If cmd==XSDRTDOE, then goto ENDDR. Otherwise, stay in ShiftDR. + * XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucEndDR; + int iErrorCode; + ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ? + pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR); + iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), + pXsvfInfo->lShiftLengthBits, + pXsvfInfo->sShiftLengthBytes, + &(pXsvfInfo->lvTdi), + &(pXsvfInfo->lvTdoCaptured), + &(pXsvfInfo->lvTdoExpected), + /*plvTdoMask*/0, ucEndDR, + /*lRunTestTime*/0, /*ucMaxRepeat*/0 ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXSTATE + * Description: XSTATE <byte> + * <byte> == XTAPSTATE; + * Get the state parameter and transition the TAP to that state. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucNextState; + int iErrorCode; + readByte( &ucNextState ); + iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState ); + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXENDXR + * Description: XENDIR/XENDDR <byte> + * <byte>: 0 = RUNTEST; 1 = PAUSE. + * Get the prespecified XENDIR or XENDDR. + * Both XENDIR and XENDDR use the same implementation. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo ) +{ + int iErrorCode; + unsigned char ucEndState; + + iErrorCode = XSVF_ERROR_NONE; + readByte( &ucEndState ); + if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) ) + { + iErrorCode = XSVF_ERROR_ILLEGALSTATE; + } + else + { + + if ( pXsvfInfo->ucCommand == XENDIR ) + { + if ( ucEndState == XENDXR_RUNTEST ) + { + pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST; + } + else + { + pXsvfInfo->ucEndIR = XTAPSTATE_PAUSEIR; + } + XSVFDBG_PRINTF1( 3, " ENDIR State = %s\n", + xsvf_pzTapState[ pXsvfInfo->ucEndIR ] ); + } + else /* XENDDR */ + { + if ( ucEndState == XENDXR_RUNTEST ) + { + pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST; + } + else + { + pXsvfInfo->ucEndDR = XTAPSTATE_PAUSEDR; + } + XSVFDBG_PRINTF1( 3, " ENDDR State = %s\n", + xsvf_pzTapState[ pXsvfInfo->ucEndDR ] ); + } + } + + if ( iErrorCode != XSVF_ERROR_NONE ) + { + pXsvfInfo->iErrorCode = iErrorCode; + } + return( iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXCOMMENT + * Description: XCOMMENT <text string ending in \0> + * <text string ending in \0> == text comment; + * Arbitrary comment embedded in the XSVF. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo ) +{ + /* Use the comment for debugging */ + /* Otherwise, read through the comment to the end '\0' and ignore */ + unsigned char ucText; + + if ( xsvf_iDebugLevel > 0 ) + { + putc( ' ' ); + } + + do + { + readByte( &ucText ); + if ( xsvf_iDebugLevel > 0 ) + { + putc( ucText ? ucText : '\n' ); + } + } while ( ucText ); + + pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfDoXWAIT + * Description: XWAIT <wait_state> <end_state> <wait_time> + * If not already in <wait_state>, then go to <wait_state>. + * Wait in <wait_state> for <wait_time> microseconds. + * Finally, if not already in <end_state>, then goto <end_state>. + * Parameters: pXsvfInfo - XSVF information pointer. + * Returns: int - 0 = success; non-zero = error. + *****************************************************************************/ +int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo ) +{ + unsigned char ucWaitState; + unsigned char ucEndState; + long lWaitTime; + + /* Get Parameters */ + /* <wait_state> */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucWaitState = pXsvfInfo->lvTdi.val[0]; + + /* <end_state> */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucEndState = pXsvfInfo->lvTdi.val[0]; + + /* <wait_time> */ + readVal( &(pXsvfInfo->lvTdi), 4 ); + lWaitTime = value( &(pXsvfInfo->lvTdi) ); + XSVFDBG_PRINTF2( 3, " XWAIT: state = %s; time = %ld\n", + xsvf_pzTapState[ ucWaitState ], lWaitTime ); + + /* If not already in <wait_state>, go to <wait_state> */ + if ( pXsvfInfo->ucTapState != ucWaitState ) + { + xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState ); + } + + /* Wait for <wait_time> microseconds */ + waitTime( lWaitTime ); + + /* If not already in <end_state>, go to <end_state> */ + if ( pXsvfInfo->ucTapState != ucEndState ) + { + xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState ); + } + + return( XSVF_ERROR_NONE ); +} + + +/*============================================================================ + * Execution Control Functions + ============================================================================*/ + +/***************************************************************************** + * Function: xsvfInitialize + * Description: Initialize the xsvf player. + * Call this before running the player to initialize the data + * in the SXsvfInfo struct. + * xsvfCleanup is called to clean up the data in SXsvfInfo + * after the XSVF is played. + * Parameters: pXsvfInfo - ptr to the XSVF information. + * Returns: int - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfInitialize( SXsvfInfo* pXsvfInfo ) +{ + /* Initialize values */ + pXsvfInfo->iErrorCode = xsvfInfoInit( pXsvfInfo ); + + if ( !pXsvfInfo->iErrorCode ) + { + /* Initialize the TAPs */ + pXsvfInfo->iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), + XTAPSTATE_RESET ); + } + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfRun + * Description: Run the xsvf player for a single command and return. + * First, call xsvfInitialize. + * Then, repeatedly call this function until an error is detected + * or until the pXsvfInfo->ucComplete variable is non-zero. + * Finally, call xsvfCleanup to cleanup any remnants. + * Parameters: pXsvfInfo - ptr to the XSVF information. + * Returns: int - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfRun( SXsvfInfo* pXsvfInfo ) +{ + /* Process the XSVF commands */ + if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) ) + { + /* read 1 byte for the instruction */ + readByte( &(pXsvfInfo->ucCommand) ); + ++(pXsvfInfo->lCommandCount); + + if ( pXsvfInfo->ucCommand < XLASTCMD ) + { + /* Execute the command. Func sets error code. */ + XSVFDBG_PRINTF1( 2, " %s\n", + xsvf_pzCommandName[pXsvfInfo->ucCommand] ); + /* If your compiler cannot take this form, + then convert to a switch statement */ +#if 0 /* test-only */ + xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo ); +#else + switch (pXsvfInfo->ucCommand) { + case 0: + xsvfDoXCOMPLETE(pXsvfInfo); /* 0 */ + break; + case 1: + xsvfDoXTDOMASK(pXsvfInfo); /* 1 */ + break; + case 2: + xsvfDoXSIR(pXsvfInfo); /* 2 */ + break; + case 3: + xsvfDoXSDR(pXsvfInfo); /* 3 */ + break; + case 4: + xsvfDoXRUNTEST(pXsvfInfo); /* 4 */ + break; + case 5: + xsvfDoIllegalCmd(pXsvfInfo); /* 5 */ + break; + case 6: + xsvfDoIllegalCmd(pXsvfInfo); /* 6 */ + break; + case 7: + xsvfDoXREPEAT(pXsvfInfo); /* 7 */ + break; + case 8: + xsvfDoXSDRSIZE(pXsvfInfo); /* 8 */ + break; + case 9: + xsvfDoXSDRTDO(pXsvfInfo); /* 9 */ + break; +#ifdef XSVF_SUPPORT_COMPRESSION + case 10: + xsvfDoXSETSDRMASKS(pXsvfInfo); /* 10 */ + break; + case 11: + xsvfDoXSDRINC(pXsvfInfo); /* 11 */ + break; +#else + case 10: + xsvfDoIllegalCmd(pXsvfInfo); /* 10 */ + break; + case 11: + xsvfDoIllegalCmd(pXsvfInfo); /* 11 */ + break; +#endif /* XSVF_SUPPORT_COMPRESSION */ + case 12: + xsvfDoXSDRBCE(pXsvfInfo); /* 12 */ + break; + case 13: + xsvfDoXSDRBCE(pXsvfInfo); /* 13 */ + break; + case 14: + xsvfDoXSDRBCE(pXsvfInfo); /* 14 */ + break; + case 15: + xsvfDoXSDRTDOBCE(pXsvfInfo); /* 15 */ + break; + case 16: + xsvfDoXSDRTDOBCE(pXsvfInfo); /* 16 */ + break; + case 17: + xsvfDoXSDRTDOBCE(pXsvfInfo); /* 17 */ + break; + case 18: + xsvfDoXSTATE(pXsvfInfo); /* 18 */ + break; + case 19: + xsvfDoXENDXR(pXsvfInfo); /* 19 */ + break; + case 20: + xsvfDoXENDXR(pXsvfInfo); /* 20 */ + break; + case 21: + xsvfDoXSIR2(pXsvfInfo); /* 21 */ + break; + case 22: + xsvfDoXCOMMENT(pXsvfInfo); /* 22 */ + break; + case 23: + xsvfDoXWAIT(pXsvfInfo); /* 23 */ + break; + } +#endif + } + else + { + /* Illegal command value. Func sets error code. */ + xsvfDoIllegalCmd( pXsvfInfo ); + } + } + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function: xsvfCleanup + * Description: cleanup remnants of the xsvf player. + * Parameters: pXsvfInfo - ptr to the XSVF information. + * Returns: void. + *****************************************************************************/ +void xsvfCleanup( SXsvfInfo* pXsvfInfo ) +{ + xsvfInfoCleanup( pXsvfInfo ); +} + + +/*============================================================================ + * xsvfExecute() - The primary entry point to the XSVF player + ============================================================================*/ + +/***************************************************************************** + * Function: xsvfExecute + * Description: Process, interpret, and apply the XSVF commands. + * See port.c:readByte for source of XSVF data. + * Parameters: none. + * Returns: int - Legacy result values: 1 == success; 0 == failed. + *****************************************************************************/ +int xsvfExecute(void) +{ + SXsvfInfo xsvfInfo; + + xsvfInitialize( &xsvfInfo ); + + while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) ) + { + xsvfRun( &xsvfInfo ); + } + + if ( xsvfInfo.iErrorCode ) + { + XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[ + ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST ) + ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] ); + XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld. See line #%ld in the XSVF ASCII file.\n", + xsvfInfo.lCommandCount, xsvfInfo.lCommandCount ); + } + else + { + XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" ); + } + + xsvfCleanup( &xsvfInfo ); + + return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); +} + + +/***************************************************************************** + * Function: do_cpld + * Description: main function. + * Specified here for creating stand-alone debug executable. + * Embedded users should call xsvfExecute() directly. + * Parameters: iArgc - number of command-line arguments. + * ppzArgv - array of ptrs to strings (command-line arguments). + * Returns: int - Legacy return value: 1 = success; 0 = error. + *****************************************************************************/ +int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int iErrorCode; + unsigned long duration; + unsigned long long startClock, endClock; + + if (argc == 2) + xsvfdata = (unsigned char *)simple_strtoul(argv[1], NULL, 16); + else { +#ifdef CONFIG_SYS_XSVF_DEFAULT_ADDR + xsvfdata = (unsigned char *)CONFIG_SYS_XSVF_DEFAULT_ADDR; +#else + printf("Usage:\ncpld %s\n", cmdtp->help); + return -1; +#endif + } + + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); + xsvf_iDebugLevel = 0; + + printf("XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION); + printf("Reading XSVF data @ %p\n", xsvfdata); + + /* Initialize the I/O. SetPort initializes I/O on first call */ + setPort( TMS, 1 ); + + /* Execute the XSVF in the file */ + startClock = get_ticks(); + iErrorCode = xsvfExecute(); + endClock = get_ticks(); + duration = (unsigned long)(endClock - startClock); + printf("\nExecution Time = %d seconds\n", (int)(duration/get_tbclk())); + + return( iErrorCode ); +} +U_BOOT_CMD( + cpld, 2, 1, do_cpld, + "program onboard CPLD", + "<xsvf-addr>" +); diff --git a/qemu/roms/u-boot/board/esd/common/xilinx_jtag/micro.h b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/micro.h new file mode 100644 index 000000000..e9a761285 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/micro.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/***************************************************************************** + * File: micro.h + * Description: This header file contains the function prototype to the + * primary interface function for the XSVF player. + * Usage: FIRST - PORTS.C + * Customize the ports.c function implementations to establish + * the correct protocol for communicating with your JTAG ports + * (setPort() and readTDOBit()) and tune the waitTime() delay + * function. Also, establish access to the XSVF data source + * in the readByte() function. + * FINALLY - Call xsvfExecute(). + *****************************************************************************/ +#ifndef XSVF_MICRO_H +#define XSVF_MICRO_H + +/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ +#define XSVF_LEGACY_SUCCESS 1 +#define XSVF_LEGACY_ERROR 0 + +/* 4.04 [NEW] Error codes for xsvfExecute. */ +/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */ +#define XSVF_ERROR_NONE 0 +#define XSVF_ERROR_UNKNOWN 1 +#define XSVF_ERROR_TDOMISMATCH 2 +#define XSVF_ERROR_MAXRETRIES 3 /* TDO mismatch after max retries */ +#define XSVF_ERROR_ILLEGALCMD 4 +#define XSVF_ERROR_ILLEGALSTATE 5 +#define XSVF_ERROR_DATAOVERFLOW 6 /* Data > lenVal MAX_LEN buffer size*/ +/* Insert new errors here */ +#define XSVF_ERROR_LAST 7 + +/***************************************************************************** + * Function: xsvfExecute + * Description: Process, interpret, and apply the XSVF commands. + * See port.c:readByte for source of XSVF data. + * Parameters: none. + * Returns: int - For error codes see above. + *****************************************************************************/ +int xsvfExecute(void); + +#endif /* XSVF_MICRO_H */ diff --git a/qemu/roms/u-boot/board/esd/common/xilinx_jtag/ports.c b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/ports.c new file mode 100644 index 000000000..d79dbd1e0 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/ports.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/*******************************************************/ +/* file: ports.c */ +/* abstract: This file contains the routines to */ +/* output values on the JTAG ports, to read */ +/* the TDO bit, and to read a byte of data */ +/* from the prom */ +/* */ +/*******************************************************/ + +#include <common.h> +#include <asm/processor.h> +#include <asm/io.h> + +#include "ports.h" + +static unsigned long output = 0; +static int filepos = 0; +static int oldstate = 0; +static int newstate = 0; +static int readptr = 0; + +extern const unsigned char *xsvfdata; + +/* if in debugging mode, then just set the variables */ +void setPort(short p,short val) +{ + if (p==TMS) { + if (val) { + output |= JTAG_TMS; + } else { + output &= ~JTAG_TMS; + } + } + if (p==TDI) { + if (val) { + output |= JTAG_TDI; + } else { + output &= ~JTAG_TDI; + } + } + if (p==TCK) { + if (val) { + output |= JTAG_TCK; + } else { + output &= ~JTAG_TCK; + } + out_be32((void *)GPIO0_OR, output); + } +} + + +/* toggle tck LH */ +void pulseClock(void) +{ + setPort(TCK,0); /* set the TCK port to low */ + setPort(TCK,1); /* set the TCK port to high */ +} + + +/* read in a byte of data from the prom */ +void readByte(unsigned char *data) +{ + /* pretend reading using a file */ + *data = xsvfdata[readptr++]; + newstate = filepos++ >> 10; + if (newstate != oldstate) { + printf("%4d kB\r\r\r\r", newstate); + oldstate = newstate; + } +} + +/* read the TDO bit from port */ +unsigned char readTDOBit(void) +{ + unsigned long inputs; + + inputs = in_be32((void *)GPIO0_IR); + if (inputs & JTAG_TDO) + return 1; + else + return 0; +} + + +/* Wait at least the specified number of microsec. */ +/* Use a timer if possible; otherwise estimate the number of instructions */ +/* necessary to be run based on the microcontroller speed. For this example */ +/* we pulse the TCK port a number of times based on the processor speed. */ +void waitTime(long microsec) +{ + udelay(microsec); /* esd */ +} diff --git a/qemu/roms/u-boot/board/esd/common/xilinx_jtag/ports.h b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/ports.h new file mode 100644 index 000000000..8ee7de92d --- /dev/null +++ b/qemu/roms/u-boot/board/esd/common/xilinx_jtag/ports.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/*******************************************************/ +/* file: ports.h */ +/* abstract: This file contains extern declarations */ +/* for providing stimulus to the JTAG ports.*/ +/*******************************************************/ + +#ifndef ports_dot_h +#define ports_dot_h + +/* these constants are used to send the appropriate ports to setPort */ +/* they should be enumerated types, but some of the microcontroller */ +/* compilers don't like enumerated types */ +#define TCK (short) 0 +#define TMS (short) 1 +#define TDI (short) 2 + +/* + * Use CONFIG_SYS_FPGA_xxx defines from board include file. + */ +#define JTAG_TMS CONFIG_SYS_FPGA_PRG /* output */ +#define JTAG_TCK CONFIG_SYS_FPGA_CLK /* output */ +#define JTAG_TDI CONFIG_SYS_FPGA_DATA /* output */ +#define JTAG_TDO CONFIG_SYS_FPGA_DONE /* input */ + +/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ +void setPort(short p, short val); + +/* read the TDO bit and store it in val */ +unsigned char readTDOBit(void); + +/* make clock go down->up->down*/ +void pulseClock(void); + +/* read the next byte of data from the xsvf file */ +void readByte(unsigned char *data); + +void waitTime(long microsec); + +#endif |