From d593528b354be3f677b5d921d3fac4d0da66700a Mon Sep 17 00:00:00 2001 From: Kolja Waschk Date: Sun, 24 Feb 2008 14:12:29 +0000 Subject: [PATCH] [ 1900847 ] MPC824x 32-bit bus support git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1089 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/ChangeLog | 4 + jtag/src/bus/mpc824x.c | 216 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 194 insertions(+), 26 deletions(-) diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 41f120fa..d77cf179 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,7 @@ +2008-02-24 Eugene Boldenkov + + * src/bus/mpc824x.c: Add 32-bit bus support (1900847) + 2008-02-24 Mike Frysinger * configure.ac: Fix building out of tree (1899908), only use libusb flags diff --git a/jtag/src/bus/mpc824x.c b/jtag/src/bus/mpc824x.c index 386251e7..f4abe2cd 100644 --- a/jtag/src/bus/mpc824x.c +++ b/jtag/src/bus/mpc824x.c @@ -49,7 +49,7 @@ typedef struct { signal_t *nrcs0; signal_t *nwe; signal_t *nfoe; - signal_t *d[8]; + signal_t *d[32]; } bus_params_t; #define CHAIN ((bus_params_t *) bus->params)->chain @@ -63,14 +63,52 @@ typedef struct { #define nFOE ((bus_params_t *) bus->params)->nfoe #define D ((bus_params_t *) bus->params)->d +int BUS_WIDTH = 8; +char REVBITS = 0; +char dbgAddr = 0; +char dbgData = 0; + + static void setup_address( bus_t *bus, uint32_t a ) { int i; part_t *p = PART; - for (i = 0; i < 23; i++) - part_set_signal( p, AR[i], 1, (a >> i) & 1 ); + switch (BUS_WIDTH) { + case 8:/* 8-bit data bus */ + for (i = 0; i < 23; i++) + part_set_signal( p, AR[i], 1, (a >> i) & 1 ); + case 32:/* 32-bit data bus */ + for (i = 0; i < 21; i++) + part_set_signal( p, AR[i], 1, (a >> (i+2)) & 1 ); + break; + case 64: + for (i = 0; i < 20; i++) + part_set_signal( p, AR[i], 1, (a >> (i+3)) & 1 ); + } + + /* Just for debugging */ + if (dbgAddr) { + int j, k; + switch (BUS_WIDTH) { + case 8: k = 23; break; + case 32: k = 21; break; + case 64: k = 20; + } + + printf(_("Addr [%2d:0]: %06X "), k, a); + for (i=0; i<3; i++) { + for (j=0; j<8; j++) + if ((i*8+j) >= (23 - k)) + printf("%1d", (a >> (23 - (i*8+j)) ) & 1); + else + printf(" "); + printf(" "); + }; + printf("\n"); + } + } static int mpc824x_bus_area( bus_t *bus, uint32_t adr, bus_area_t *area ); @@ -83,7 +121,7 @@ set_data_in( bus_t *bus, uint32_t adr ) bus_area_t area; mpc824x_bus_area( bus, adr, &area ); - if (area.width > 8) + if (area.width > 64) return; for (i = 0; i < area.width; i++) @@ -98,11 +136,32 @@ setup_data( bus_t *bus, uint32_t adr, uint32_t d ) bus_area_t area; mpc824x_bus_area( bus, adr, &area ); - if (area.width > 8) - return; + if (area.width > 64) + return; for (i = 0; i < area.width; i++) - part_set_signal( p, D[i], 1, (d >> i) & 1 ); + part_set_signal( p, D[i], 1, (d >> ((REVBITS==1) ? BUS_WIDTH-1-i : i)) & 1 ); + + /* Just for debugging */ + if (dbgData) { + printf(_("Data WR [%d:0]: %08X "), area.width-1, d); + int j; + int bytes =0; + if (BUS_WIDTH==8) bytes = 1; + else if (BUS_WIDTH==32) bytes = 4; + else if (BUS_WIDTH==64) bytes = 4; /* Needs to be fixed - d is 32-bit long, so no 64 bit mode is possible */ + + for (i=0; i> (BUS_WIDTH-1 - (i*8+j)) ) & 1); + else + printf("%1d", (d >> ( (i*8+j)) ) & 1); + printf(" "); + }; + printf("\n"); + } + } static uint32_t @@ -114,11 +173,31 @@ get_data( bus_t *bus, uint32_t adr ) part_t *p = PART; mpc824x_bus_area( bus, adr, &area ); - if (area.width > 8) + if (area.width > 64) return 0; for (i = 0; i < area.width; i++) - d |= (uint32_t) (part_get_signal( p, D[i] ) << i); + d |= (uint32_t) (part_get_signal( p, D[i] ) << ((REVBITS==1) ? BUS_WIDTH-1-i : i)); + + /* Just for debugging */ + if (dbgData) { + printf(_("Data RD [%d:0]: %08X "), area.width-1, d); + int j; + int bytes = 0; + if (BUS_WIDTH==8) bytes = 1; + else if (BUS_WIDTH==32) bytes = 4; + else if (BUS_WIDTH==64) bytes = 4; /* Needs to be fixed - d is 32-bit long, so no 64 bit mode is possible */ + + for (i=0; i> (BUS_WIDTH-1 - (i*8+j)) ) & 1); + else + printf("%1d", (d >> ( (i*8+j)) ) & 1); + printf(" "); + }; + printf("\n"); + } return d; } @@ -195,15 +274,18 @@ mpc824x_bus_read( bus_t *bus, uint32_t adr ) static void mpc824x_bus_write( bus_t *bus, uint32_t adr, uint32_t data ) { - /* see Figure 6-47 in [1] */ part_t *p = PART; - chain_t *chain = CHAIN; + LAST_ADR = adr; + + + /* see Figure 6-47 in [1] */ part_set_signal( p, nRCS0, 1, 0 ); part_set_signal( p, nWE, 1, 1 ); part_set_signal( p, nFOE, 1, 1 ); setup_address( bus, adr ); + setup_data( bus, adr, data ); chain_shift_data_registers( chain, 0 ); @@ -211,12 +293,17 @@ mpc824x_bus_write( bus_t *bus, uint32_t adr, uint32_t data ) part_set_signal( p, nWE, 1, 0 ); chain_shift_data_registers( chain, 0 ); part_set_signal( p, nWE, 1, 1 ); + part_set_signal( p, nRCS0, 1, 1 ); chain_shift_data_registers( chain, 0 ); + + + } static int mpc824x_bus_area( bus_t *bus, uint32_t adr, bus_area_t *area ) { + if (adr < UINT32_C(0xFF000000)) { area->description = NULL; area->start = UINT32_C(0x00000000); @@ -239,7 +326,7 @@ mpc824x_bus_area( bus_t *bus, uint32_t adr, bus_area_t *area ) area->description = N_("Base ROM Interface (Bank 0)"); area->start = UINT32_C(0xFF800000); area->length = UINT64_C(0x00800000); - area->width = (boot_nFOE != 0) ? 8 : 0; + area->width = BUS_WIDTH; return 0; } @@ -249,7 +336,7 @@ mpc824x_bus_area( bus_t *bus, uint32_t adr, bus_area_t *area ) area->description = NULL; area->start = UINT32_C(0xFF800000); area->length = UINT64_C(0x00400000); - area->width = 0; + area->width = BUS_WIDTH; return 0; } @@ -257,7 +344,7 @@ mpc824x_bus_area( bus_t *bus, uint32_t adr, bus_area_t *area ) area->description = N_("Base ROM Interface (Bank 0)"); area->start = UINT32_C(0xFFC00000); area->length = UINT64_C(0x00400000); - area->width = (boot_nFOE != 0) ? 8 : 0; + area->width = BUS_WIDTH; return 0; } @@ -280,6 +367,68 @@ mpc824x_bus_new( char *cmd_params[] ) signal_t *s_nfoe; signal_t *s_sdma1; + char param[16], value[16]; + + char dfltWidth = 1; + + dbgAddr = 0; + dbgData = 0; + REVBITS = 0; + + for (i=2; cmd_params[i]; i++) { + if (strstr( cmd_params[i], "=")) { + sscanf( cmd_params[i], "%[^=]%*c%s", param, value ); + + if (!strcmp( "width", param )) { + if (!strcmp( "8", value )) { + BUS_WIDTH = 8; + dfltWidth = 0; + } else if (!strcmp( "32", value )) { + BUS_WIDTH = 32; + dfltWidth = 0; + } + else if (!strcmp( "64", value )) { + // BUS_WIDTH = 64; // Needs to fix, look at setup_data() + BUS_WIDTH = 32; + printf(_(" Bus width 64 exists in mpc824x, but not supported by UrJTAG currently\n")); + dfltWidth = 1; + } + else { + printf(_(" Only 8,32 and 64 bus width are supported for Banks 0 and 1\n")); + return NULL; + } + } + } else { + if (!strcmp( "revbits", cmd_params[i])) + REVBITS = 1; + + if (!strcmp( "help", cmd_params[i])) { + printf(_("Usage: initbus mpc824x [width=WIDTH] [revbits] [dbgAddr] [dbgData]\n\n" + " WIDTH data bus width - 8, 32, 64 (default 8)\n" + " revbits reverse bits in data bus (default - no)\n" + " dbgAddr display address bus state (default - no)\n" + " dbgData display data bus state (default - no)\n")); + return NULL; + } + + if (!strcmp( "dbgAddr", cmd_params[i])) + dbgAddr = 1; + + + if (!strcmp( "dbgData", cmd_params[i])) + dbgData = 1; + + + } + + } + if (dfltWidth) + printf(_(" Using default bus width %d\n"), BUS_WIDTH); + + // REVBITS = 0; + + + if (!chain || !chain->parts || chain->parts->len <= chain->active_part || chain->active_part < 0) return NULL; @@ -312,6 +461,7 @@ mpc824x_bus_new( char *cmd_params[] ) boot_nFOE = part_get_signal( part, s_nfoe ); boot_SDMA1 = part_get_signal( part, s_sdma1 ); + for (i = 0; i <= 10; i++) { sprintf( buff, "SDMA%d", i ); AR[i] = part_find_signal( part, buff ); @@ -342,14 +492,16 @@ mpc824x_bus_new( char *cmd_params[] ) } AR[21] = part_find_signal( part, "SDMA11" ); if (!AR[21]) { - printf( _("signal '%s' not found\n"), "SDMA11" ); - failed = 1; + printf( _("signal '%s' not found\n"), "SDMA11" ); + failed = 1; } AR[22] = part_find_signal( part, "SDMA12" ); if (!AR[22]) { - printf( _("signal '%s' not found\n"), "SDMA12" ); - failed = 1; + printf( _("signal '%s' not found\n"), "SDMA12" ); + failed = 1; } + + nRCS0 = part_find_signal( part, "nRCS0" ); if (!nRCS0) { printf( _("signal '%s' not found\n"), "nRCS0" ); @@ -365,14 +517,26 @@ mpc824x_bus_new( char *cmd_params[] ) printf( _("signal '%s' not found\n"), "nFOE" ); failed = 1; } - for (i = 0; i < 8; i++) { - sprintf( buff, "MDH%d", i ); - D[7 - i] = part_find_signal( part, buff ); - if (!D[7 - i]) { - printf( _("signal '%s' not found\n"), buff ); - failed = 1; - break; - } + + /* + Freescale MPC824x uses inversed bit order ([1], p. 2-18): + msb is MDH[0] while lsb is MDH[31] + Flash chips usually use another bit orded: + msb is D[31] and lsb is D[0] + + This should be rewired in the PCB (MDH[0] - D[31], ..., MDH[31] - D[0]). + Otherwise you will have to use "revbits" UrJTAG parameter and + binary files with reversed bit order. + */ + + for (i = 0; i < 32; i++) { /* Needs to be fixed for 64-bit bus width */ + sprintf( buff, "MDH%d", 31 - i ); + D[i] = part_find_signal( part, buff ); + if (!D[i]) { + printf( _("signal '%s' not found\n"), buff ); + failed = 1; + break; + } } if (failed) {