From e68bf276bd8a3f19479113d61e7d9d8309f725c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Sat, 16 May 2009 21:11:59 +0000 Subject: [PATCH] [ 2770421 ] Patch: Support for IXP43x (Florian Boor) without jtag description files git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1599 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- urjtag/ChangeLog | 5 + urjtag/THANKS | 1 + urjtag/configure.ac | 3 +- urjtag/src/bus/Makefile.am | 4 + urjtag/src/bus/buses.c | 3 + urjtag/src/bus/buses.h | 1 + urjtag/src/bus/ixp435.c | 305 +++++++++++++++++++++++++++++++++++++ 7 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 urjtag/src/bus/ixp435.c diff --git a/urjtag/ChangeLog b/urjtag/ChangeLog index 0ac53004..63125010 100644 --- a/urjtag/ChangeLog +++ b/urjtag/ChangeLog @@ -1,5 +1,10 @@ 2009-05-16 Arnim Laeuger + * src/bus/ixp435.c, src/bus/buses.c, src/bus/buses.h, + src/bus/Makefile.am, configure.ac, THANKS: + [ 2770421 ] Patch: Support for IXP43x (Florian Boor) + without jtag description files + * include/urjtag/parport.h, src/tap/parport/ppdev.c, src/tap/parport/ppi.c, src/tap/parport/direct.c, src/tap/parport.c: [ 2782584 ] PPWDATA and PPWCONTROL ioclts take unsigned char not uint8_t (Yen Rui) diff --git a/urjtag/THANKS b/urjtag/THANKS index 7cb6b7e3..78779194 100644 --- a/urjtag/THANKS +++ b/urjtag/THANKS @@ -10,6 +10,7 @@ Michael Banditt Krzysztof Blaszkowski Eugene Boldenkov Uwe Bonnes +Florian Boor Cliff Brake Martin Buck Ian Campbell diff --git a/urjtag/configure.ac b/urjtag/configure.ac index 93a75c6b..d5f44494 100644 --- a/urjtag/configure.ac +++ b/urjtag/configure.ac @@ -415,7 +415,7 @@ AC_DEFUN([CHECK_DRIVER], [ # Enable bus drivers AC_DEFUN([DEF_ENABLE_BUSDRIVERS], [\ au1500 avr32 bcm1250 bf526_ezkit bf527_ezkit bf533_stamp bf533_ezkit bf537_stamp bf537_ezkit bf538f_ezkit bf548_ezkit bf561_ezkit bscoach ejtag ejtag_dma\ -fjmem ixp425 jopcyc h7202 lh7a400 mpc5200 mpc824x ppc405ep ppc440gx_ebc8 prototype pxa2x0 pxa27x \ +fjmem ixp425 ixp435 jopcyc h7202 lh7a400 mpc5200 mpc824x ppc405ep ppc440gx_ebc8 prototype pxa2x0 pxa27x \ s3c4510 sa1110 sh7727 sh7750r sh7751r sharc_21065L slsup3 tx4925 zefant_xs3]) AC_ARG_ENABLE(bus, [AS_HELP_STRING([--enable-bus], [Enable default set or specific bus drivers:])] @@ -449,6 +449,7 @@ CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [ejtag], [ENABLE_BUS_ CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [ejtag_dma], [ENABLE_BUS_EJTAG_DMA]) CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [fjmem], [ENABLE_BUS_FJMEM]) CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [ixp425], [ENABLE_BUS_IXP425]) +CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [ixp435], [ENABLE_BUS_IXP435]) CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [jopcyc], [ENABLE_BUS_JOPCYC]) CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [h7202], [ENABLE_BUS_H7202]) CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [lh7a400], [ENABLE_BUS_LH7A400]) diff --git a/urjtag/src/bus/Makefile.am b/urjtag/src/bus/Makefile.am index 3bf7bd2e..91ec907e 100644 --- a/urjtag/src/bus/Makefile.am +++ b/urjtag/src/bus/Makefile.am @@ -106,6 +106,10 @@ if ENABLE_BUS_IXP425 libbus_la_SOURCES += ixp425.c endif +if ENABLE_BUS_IXP435 +libbus_la_SOURCES += ixp435.c +endif + if ENABLE_BUS_JOPCYC libbus_la_SOURCES += jopcyc.c endif diff --git a/urjtag/src/bus/buses.c b/urjtag/src/bus/buses.c index 1bf173c2..11fd4115 100644 --- a/urjtag/src/bus/buses.c +++ b/urjtag/src/bus/buses.c @@ -82,6 +82,9 @@ const urj_bus_driver_t *urj_bus_drivers[] = { #ifdef ENABLE_BUS_IXP425 &urj_bus_ixp425_bus, #endif +#ifdef ENABLE_BUS_IXP435 + &urj_bus_ixp435_bus, +#endif #ifdef ENABLE_BUS_JOPCYC &urj_bus_jopcyc_bus, #endif diff --git a/urjtag/src/bus/buses.h b/urjtag/src/bus/buses.h index 6a5d7737..8e7b3cd0 100644 --- a/urjtag/src/bus/buses.h +++ b/urjtag/src/bus/buses.h @@ -42,6 +42,7 @@ extern const urj_bus_driver_t urj_bus_ejtag_bus; extern const urj_bus_driver_t urj_bus_fjmem_bus; extern const urj_bus_driver_t urj_bus_h7202_bus; extern const urj_bus_driver_t urj_bus_ixp425_bus; +extern const urj_bus_driver_t urj_bus_ixp435_bus; extern const urj_bus_driver_t urj_bus_jopcyc_bus; extern const urj_bus_driver_t urj_bus_lh7a400_bus; extern const urj_bus_driver_t urj_bus_mpc5200_bus; diff --git a/urjtag/src/bus/ixp435.c b/urjtag/src/bus/ixp435.c new file mode 100644 index 00000000..d39c381c --- /dev/null +++ b/urjtag/src/bus/ixp435.c @@ -0,0 +1,305 @@ +/* + * $Id$ + * + * Copyright (C) 2002 ETC s.r.o. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by Christian Pellegrin , 2003. + * Modified by Marcel Telka , 2003. + * Adapted for IXP43x by Florian Boor , 2009. + * + */ + +#include "sysdep.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include "buses.h" +#include "generic_bus.h" + +typedef struct { + urj_part_signal_t *ex_cs[4]; + urj_part_signal_t *ex_addr[24]; + urj_part_signal_t *ex_data[16]; + urj_part_signal_t *ex_wr; + urj_part_signal_t *ex_rd; +} bus_params_t; + +#define EX_CS ((bus_params_t *) bus->params)->ex_cs +#define EX_ADDR ((bus_params_t *) bus->params)->ex_addr +#define EX_DATA ((bus_params_t *) bus->params)->ex_data +#define EX_WR ((bus_params_t *) bus->params)->ex_wr +#define EX_RD ((bus_params_t *) bus->params)->ex_rd + +/** + * bus->driver->(*new_bus) + * + */ +static urj_bus_t * +ixp435_bus_new (urj_chain_t *chain, const urj_bus_driver_t *driver, + char *cmd_params[]) +{ + urj_bus_t *bus; + urj_part_t *part; + char buff[15]; + int i; + int failed = 0; + + bus = calloc (1, sizeof (urj_bus_t)); + if (!bus) + { + urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "calloc(%zd,%zd) fails", + 1, sizeof (urj_bus_t)); + return NULL; + } + + bus->driver = driver; + bus->params = calloc (1, sizeof (bus_params_t)); + if (!bus->params) + { + free (bus); + urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "calloc(%zd,%zd) fails", + 1, sizeof (bus_params_t)); + return NULL; + } + + bus->chain = chain; + bus->part = part = chain->parts->parts[chain->active_part]; + + for (i = 0; i < 4; i++) { + sprintf (buff, "ex_cs_n%d", i); + failed |= urj_bus_generic_attach_sig (part, &(EX_CS[i]), buff); + } + + for (i = 0; i < 24; i++) { + sprintf (buff, "ex_addr%d", i); + failed |= urj_bus_generic_attach_sig (part, &(EX_ADDR[i]), buff); + } + + for (i = 0; i < 16; i++) { + sprintf (buff, "ex_data%d", i); + failed |= urj_bus_generic_attach_sig (part, &(EX_DATA[i]), buff); + } + + failed |= urj_bus_generic_attach_sig (part, &(EX_WR), "ex_wr_n"); + + failed |= urj_bus_generic_attach_sig (part, &(EX_RD), "ex_rd_n"); + + if (failed) { + free (bus->params); + free (bus); + return NULL; + } + + return bus; +} + +/** + * bus->driver->(*printinfo) + * + */ +static void +ixp435_bus_printinfo (urj_log_level_t ll, urj_bus_t *bus) +{ + int i; + + for (i = 0; i < bus->chain->parts->len; i++) + if (bus->part == bus->chain->parts->parts[i]) + break; + urj_log (ll, _("Intel IXP435 compatible bus driver (JTAG part No. %d)\n"), + i); +} + +/** + * bus->driver->(*area) + * + */ +static int +ixp435_bus_area (urj_bus_t *bus, uint32_t adr, urj_bus_area_t *area) +{ + area->description = NULL; + area->start = UINT32_C(0x00000000); + area->length = UINT64_C(0x100000000); + area->width = 16; + + return URJ_STATUS_OK; +} + +static void +select_flash (urj_bus_t *bus) +{ + urj_part_t *p = bus->part; + + urj_part_set_signal (p, EX_CS[0], 1, 0); + urj_part_set_signal (p, EX_CS[1], 1, 1); + urj_part_set_signal (p, EX_CS[2], 1, 1); + urj_part_set_signal (p, EX_CS[3], 1, 1); +} + +static void +unselect_flash (urj_bus_t *bus) +{ + urj_part_t *p = bus->part; + + urj_part_set_signal (p, EX_CS[0], 1, 1); + urj_part_set_signal (p, EX_CS[1], 1, 1); + urj_part_set_signal (p, EX_CS[2], 1, 1); + urj_part_set_signal (p, EX_CS[3], 1, 1); +} + +static void +setup_address (urj_bus_t *bus, uint32_t a) +{ + int i; + urj_part_t *p = bus->part; + + for (i = 0; i < 24; i++) + urj_part_set_signal (p, EX_ADDR[i], 1, (a >> i) & 1); +} + +static void +set_data_in (urj_bus_t *bus) +{ + int i; + urj_part_t *p = bus->part; + + for (i = 0; i < 16; i++) + urj_part_set_signal (p, EX_DATA[i], 0, 0); +} + +static void +setup_data (urj_bus_t *bus, uint32_t d) +{ + int i; + urj_part_t *p = bus->part; + + for (i = 0; i < 16; i++) + urj_part_set_signal (p, EX_DATA[i], 1, (d >> i) & 1); +} + +/** + * bus->driver->(*read_start) + * + */ +static void +ixp435_bus_read_start (urj_bus_t *bus, uint32_t adr) +{ + urj_part_t *p = bus->part; + urj_chain_t *chain = bus->chain; + + select_flash (bus); + urj_part_set_signal (p, EX_RD, 1, 0); + urj_part_set_signal (p, EX_WR, 1, 1); + + setup_address (bus, adr); + set_data_in (bus); + + urj_tap_chain_shift_data_registers (chain, 0); +} + +/** + * bus->driver->(*read_next) + * + */ +static uint32_t +ixp435_bus_read_next (urj_bus_t *bus, uint32_t adr) +{ + urj_part_t *p = bus->part; + urj_chain_t *chain = bus->chain; + int i; + uint32_t d = 0; + + setup_address (bus, adr); + urj_tap_chain_shift_data_registers (chain, 1); + + for (i = 0; i < 16; i++) + d |= (uint32_t) (urj_part_get_signal (p, EX_DATA[i] ) << i); + + return d; +} + +/** + * bus->driver->(*read_end) + * + */ +static uint32_t +ixp435_bus_read_end (urj_bus_t *bus) +{ + urj_part_t *p = bus->part; + urj_chain_t *chain = bus->chain; + int i; + uint32_t d = 0; + + unselect_flash (bus); + urj_part_set_signal (p, EX_RD, 1, 1); + urj_part_set_signal (p, EX_WR, 1, 1); + + urj_tap_chain_shift_data_registers (chain, 1); + + for (i = 0; i < 16; i++) + d |= (uint32_t) (urj_part_get_signal (p, EX_DATA[i] ) << i); + + return d; +} + +/** + * bus->driver->(*write) + * + */ +static void +ixp435_bus_write (urj_bus_t *bus, uint32_t adr, uint32_t data) +{ + urj_part_t *p = bus->part; + urj_chain_t *chain = bus->chain; + + select_flash (bus); + urj_part_set_signal (p, EX_RD, 1, 1); + + setup_address (bus, adr); + setup_data (bus, data); + + urj_tap_chain_shift_data_registers (chain, 0); + + urj_part_set_signal (p, EX_WR, 1, 0); + urj_tap_chain_shift_data_registers (chain, 0); + urj_part_set_signal (p, EX_WR, 1, 1); + unselect_flash (bus); + urj_tap_chain_shift_data_registers (chain, 0); +} + +const urj_bus_driver_t urj_bus_ixp435_bus = { + "ixp435", + N_("Intel IXP435 compatible bus driver"), + ixp435_bus_new, + urj_bus_generic_free, + ixp435_bus_printinfo, + urj_bus_generic_prepare_extest, + ixp435_bus_area, + ixp435_bus_read_start, + ixp435_bus_read_next, + ixp435_bus_read_end, + urj_bus_generic_read, + ixp435_bus_write, + urj_bus_generic_no_init +};