diff --git a/jtag/include/jim.h b/jtag/include/jim.h index d8941769..83a255db 100644 --- a/jtag/include/jim.h +++ b/jtag/include/jim.h @@ -35,6 +35,7 @@ #define JIM_H 1 #include +#include typedef enum { @@ -68,8 +69,8 @@ typedef struct jim_device struct jim_device *prev; tap_state_t tap_state; - void (*tck_rise)(struct jim_device *dev, int tms, int tdi); - void (*tck_fall)(struct jim_device *dev); + void (*tck_rise)(struct jim_device *dev, int tms, int tdi, uint8_t *shmem, size_t shmem_size); + void (*tck_fall)(struct jim_device *dev, uint8_t *shmem, size_t shmem_size); void (*dev_free)(struct jim_device *dev); void *state; int num_sregs; @@ -83,18 +84,24 @@ jim_device_t; typedef struct jim_state { int trst; + uint8_t *shmem; + size_t shmem_size; jim_device_t *last_device_in_chain; } jim_state_t; typedef struct jim_bus_device { - int width; /* bits */ - uint32_t size; /* bytes */ - void *state; /* device-dependent */ + int width; /* bytes */ + int size ; /* words (each bytes) */ + void *state; /* device-dependent */ void (*init)(struct jim_bus_device *x); - void (*access)(struct jim_bus_device *x, - uint32_t address, uint32_t data, uint32_t control); + uint32_t (*capture)(struct jim_bus_device *x, + uint32_t address, uint32_t control, + uint8_t *shmem, size_t shmem_size); + void (*update)(struct jim_bus_device *x, + uint32_t address, uint32_t data, uint32_t control, + uint8_t *shmem, size_t shmem_size); void (*free)(struct jim_bus_device *x); } jim_bus_device_t; @@ -102,6 +109,8 @@ jim_bus_device_t; typedef struct { uint32_t offset; + int adr_shift; + int data_shift; jim_bus_device_t *part; } jim_attached_part_t; diff --git a/jtag/src/jim/README.jim b/jtag/src/jim/README.jim index 64273970..183415a7 100644 --- a/jtag/src/jim/README.jim +++ b/jtag/src/jim/README.jim @@ -8,9 +8,6 @@ cable jim bsdl path . detect -initbus prototype amsb=A(31) alsb=A(0) dmsb=D(31) dlsb=D(0) cs=CS oe=OE we=WE amode=x32 +initbus prototype amsb=A(31) alsb=A(1) dmsb=D(15) dlsb=D(0) cs=CS oe=OE we=WE amode=x16 detectflash 0x0000 - - - diff --git a/jtag/src/jim/intel_28f800b3.c b/jtag/src/jim/intel_28f800b3.c index 3301e2b4..e7d8c5ce 100644 --- a/jtag/src/jim/intel_28f800b3.c +++ b/jtag/src/jim/intel_28f800b3.c @@ -1,27 +1,191 @@ +/* + * $Id: tap.c $ + * + * Copyright (C) 2008 Kolja Waschk + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This code simulates an Intel Advanced Boot Block Flash Memory (B3) 28FxxxB3. + * The simulation is based on documentation found in the corresponding datasheet, + * Order Number 290580, Revision: 020, 18 Aug 2005. + */ + #include #include #include +#include + +typedef enum +{ + READ_ARRAY, + READ_STATUS, + READ_ID, + PROG_SETUP, + PROG_CONTINUE, + PROG_SUSP_TO_READ_STATUS, + PROG_SUSP_TO_READ_ARRAY, + PROG_SUSP_TO_READ_ID, + PROG_COMPLETE, + ERASE_SETUP, + ERASE_ERROR, + ERASE_CONTINUE, + ERASE_SUSP_TO_READ_STATUS, + ERASE_SUSP_TO_READ_ARRAY, + ERASE_SUSP_TO_READ_ID, + ERASE_COMPLETE +} +intel_f28xxxb3_op_state_t; -void intel_28f800b3_init(jim_bus_device_t *d) +typedef enum { + TOP = 0, + BOTTOM = 1 } +b3_boot_type_t; -void intel_28f800b3_free(jim_bus_device_t *d) +typedef struct { + uint16_t identifier; + uint32_t control_buffer; + uint8_t status, status_buffer; + intel_f28xxxb3_op_state_t opstate; + b3_boot_type_t boot_type; } +intel_f28xxxb3_state_t; -void intel_28f800b3_access(jim_bus_device_t *d, - uint32_t address, uint32_t data, uint32_t control) +void intel_28fxxxb3_init(jim_bus_device_t *d, uint16_t id, b3_boot_type_t bt) { + d->state = malloc(sizeof(intel_f28xxxb3_state_t)); + if(d->state != NULL) + { + intel_f28xxxb3_state_t *is = d->state; + is->opstate = READ_ARRAY; + is->identifier = id; + is->boot_type = bt; + is->status = 0x00; + is->status_buffer = 0x00; + is->control_buffer = 0x00000000; + } +} + +void intel_28f800b3t_init(jim_bus_device_t *d) +{ + intel_28fxxxb3_init(d, 0x8893, BOTTOM); +} + +void intel_28fxxxb3_free(jim_bus_device_t *d) +{ + if(d->state != NULL) free(d->state); +} + +uint32_t intel_28fxxxb3_capture(jim_bus_device_t *d, + uint32_t address, uint32_t control, + uint8_t *shmem, size_t shmem_size) +{ + uint32_t data = 0; + + if((control&7) == 5) /* OE and CS: READ */ + { + intel_f28xxxb3_state_t *is = d->state; + switch(is->opstate) + { + case READ_STATUS: + data = is->status_buffer; + break; + case READ_ID: + if(address == 0) data = is->identifier; + else if(address == 1) data = 0x0089; + break; + case READ_ARRAY: + data = shmem[(address<<1)]<<8; + data |= shmem[(address<<1)]+1; + break; + default: + break; + } + } + + printf("capture A=%08X, D=%08X%s%s%s\n", address, data, + (control & 1) ? ", OE":"", + (control & 2) ? ", WE":"", + (control & 4) ? ", CS":""); + + return data; +} + +void intel_28fxxxb3_update(jim_bus_device_t *d, + uint32_t address, uint32_t data, uint32_t control, + uint8_t *shmem, size_t shmem_size) +{ + printf("update A=%08X, D=%08X%s%s%s\n", address, data, + (control & 1) ? ", OE":"", + (control & 2) ? ", WE":"", + (control & 4) ? ", CS":""); + + if(d->state != NULL) + { + intel_f28xxxb3_state_t *is = d->state; + if( (((is->control_buffer&1)==0) && ((control&1)==1)) /* OE rise */ + ||(((is->control_buffer&4)==0) && ((control&4)==1))) /* CS rise */ + { + is->status_buffer = is->status; /* latch status */ + }; + + if(((control&7)==6)&&((is->control_buffer&2)!=2)) /* WE rise, CS active: WRITE */ + { + intel_f28xxxb3_state_t *is = d->state; + uint8_t dl = data & 0xFF; + switch(is->opstate) + { + case READ_ARRAY: + case READ_STATUS: + case READ_ID: + switch(dl) + { + case 0x10: + case 0x40: is->opstate = PROG_SETUP; break; + case 0x20: is->opstate = ERASE_SETUP; break; + case 0x70: is->opstate = READ_STATUS; break; + case 0x90: is->opstate = READ_ID; break; + case 0xD0: is->opstate = READ_ARRAY; break; + case 0xB0: is->opstate = READ_ARRAY; break; + case 0xFF: is->opstate = READ_ARRAY; break; + + default: is->opstate = READ_ARRAY; break; + } + break; + default: + break; + } + }; + is->control_buffer = control; + } } -jim_bus_device_t intel_28f800b3 = +jim_bus_device_t intel_28f800b3t = { - 16, /* width [bits] */ - 0x800, /* size [bytes] */ - NULL, /* state */ - intel_28f800b3_init, /* init() */ - intel_28f800b3_access, /* access() */ - intel_28f800b3_free /* free() */ + 2, /* width [bytes] */ + 0x80000, /* size [words, each bytes] */ + NULL, /* state */ + intel_28f800b3t_init, /* init() */ + intel_28fxxxb3_capture, /* access() */ + intel_28fxxxb3_update, /* access() */ + intel_28fxxxb3_free /* free() */ }; diff --git a/jtag/src/jim/some_cpu.bsd b/jtag/src/jim/some_cpu.bsd index 5de4a796..1a748b27 100644 --- a/jtag/src/jim/some_cpu.bsd +++ b/jtag/src/jim/some_cpu.bsd @@ -23,8 +23,20 @@ -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. -- --- #/usr/bin/perl --- +-- +-- +-- The following Perl code has been used to create the BSR mapping. +-- It is aligned for easy access to the register in the some_cpu.c code: +-- +-- 31.. 0 address output A31..A0 (A0 addresses bytes!) +-- 63..32 data output (from CPU to attached parts) D31..D0 +-- 95..64 data input (from attached parts to CPU) D31..D0 +-- 96 control output OE +-- 97 control output WE +-- 98 control output CS +-- 99 control input RESET +-- +-- -- sub io_pin($$$$$) -- { -- my ($inbitno, $outbitno, $ctrlbitno, $name,$dir) = @_; @@ -42,20 +54,25 @@ -- -- ####################################### -- --- $bsi = 68; +-- io_pin(100, 96, 103, 'OE','out'); +-- io_pin(101, 97, 104, 'WE','out'); +-- io_pin(102, 98, 105, 'CS','out'); +-- io_pin(99, 0, 0, 'RESET','in'); +-- $bsi = 106; -- -- for(my $i=0;$i<32; $i++) { +-- # address output in 0.. 31 +-- # address buffer in +-- # address control in -- io_pin($i+$bsi,$i,$i+$bsi+32,sprintf('A(%d)',$i),'out'); -- } -- for(my $i=0;$i<32; $i++) { --- io_pin($i+$bsi+64, $i+32, $i+$bsi+96, sprintf('D(%d)',$i), 'inout'); +-- # data output in 32.. 63 +-- # data input in 64.. 95 +-- # data control in +-- io_pin($i+64, $i+32, $i+$bsi+64, sprintf('D(%d)',$i), 'inout'); -- }; --- --- io_pin(196, 64, 197, 'OE','out'); --- io_pin(198, 65, 199, 'WE','out'); --- io_pin(200, 66, 201, 'CS','out'); --- io_pin(67, 0, 0, 'RESET','in'); --- + entity some_cpu is @@ -116,208 +133,208 @@ attribute BOUNDARY_LENGTH of some_cpu : entity is 202 ; attribute BOUNDARY_REGISTER of some_cpu : entity is -"68 (BC_1, *, internal, X), " & -"0 (BC_1, A(0), output3, X, 100, 0, Z), " & -"100 (BC_1, *, control, 0), " & -"69 (BC_1, *, internal, X), " & -"1 (BC_1, A(1), output3, X, 101, 0, Z), " & -"101 (BC_1, *, control, 0), " & -"70 (BC_1, *, internal, X), " & -"2 (BC_1, A(2), output3, X, 102, 0, Z), " & -"102 (BC_1, *, control, 0), " & -"71 (BC_1, *, internal, X), " & -"3 (BC_1, A(3), output3, X, 103, 0, Z), " & +"100 (BC_1, *, internal, X), " & +"96 (BC_1, OE, output3, X, 103, 0, Z), " & "103 (BC_1, *, control, 0), " & -"72 (BC_1, *, internal, X), " & -"4 (BC_1, A(4), output3, X, 104, 0, Z), " & +"101 (BC_1, *, internal, X), " & +"97 (BC_1, WE, output3, X, 104, 0, Z), " & "104 (BC_1, *, control, 0), " & -"73 (BC_1, *, internal, X), " & -"5 (BC_1, A(5), output3, X, 105, 0, Z), " & +"102 (BC_1, *, internal, X), " & +"98 (BC_1, CS, output3, X, 105, 0, Z), " & "105 (BC_1, *, control, 0), " & -"74 (BC_1, *, internal, X), " & -"6 (BC_1, A(6), output3, X, 106, 0, Z), " & -"106 (BC_1, *, control, 0), " & -"75 (BC_1, *, internal, X), " & -"7 (BC_1, A(7), output3, X, 107, 0, Z), " & -"107 (BC_1, *, control, 0), " & -"76 (BC_1, *, internal, X), " & -"8 (BC_1, A(8), output3, X, 108, 0, Z), " & -"108 (BC_1, *, control, 0), " & -"77 (BC_1, *, internal, X), " & -"9 (BC_1, A(9), output3, X, 109, 0, Z), " & -"109 (BC_1, *, control, 0), " & -"78 (BC_1, *, internal, X), " & -"10 (BC_1, A(10), output3, X, 110, 0, Z), " & -"110 (BC_1, *, control, 0), " & -"79 (BC_1, *, internal, X), " & -"11 (BC_1, A(11), output3, X, 111, 0, Z), " & -"111 (BC_1, *, control, 0), " & -"80 (BC_1, *, internal, X), " & -"12 (BC_1, A(12), output3, X, 112, 0, Z), " & -"112 (BC_1, *, control, 0), " & -"81 (BC_1, *, internal, X), " & -"13 (BC_1, A(13), output3, X, 113, 0, Z), " & -"113 (BC_1, *, control, 0), " & -"82 (BC_1, *, internal, X), " & -"14 (BC_1, A(14), output3, X, 114, 0, Z), " & -"114 (BC_1, *, control, 0), " & -"83 (BC_1, *, internal, X), " & -"15 (BC_1, A(15), output3, X, 115, 0, Z), " & -"115 (BC_1, *, control, 0), " & -"84 (BC_1, *, internal, X), " & -"16 (BC_1, A(16), output3, X, 116, 0, Z), " & -"116 (BC_1, *, control, 0), " & -"85 (BC_1, *, internal, X), " & -"17 (BC_1, A(17), output3, X, 117, 0, Z), " & -"117 (BC_1, *, control, 0), " & -"86 (BC_1, *, internal, X), " & -"18 (BC_1, A(18), output3, X, 118, 0, Z), " & -"118 (BC_1, *, control, 0), " & -"87 (BC_1, *, internal, X), " & -"19 (BC_1, A(19), output3, X, 119, 0, Z), " & -"119 (BC_1, *, control, 0), " & -"88 (BC_1, *, internal, X), " & -"20 (BC_1, A(20), output3, X, 120, 0, Z), " & -"120 (BC_1, *, control, 0), " & -"89 (BC_1, *, internal, X), " & -"21 (BC_1, A(21), output3, X, 121, 0, Z), " & -"121 (BC_1, *, control, 0), " & -"90 (BC_1, *, internal, X), " & -"22 (BC_1, A(22), output3, X, 122, 0, Z), " & -"122 (BC_1, *, control, 0), " & -"91 (BC_1, *, internal, X), " & -"23 (BC_1, A(23), output3, X, 123, 0, Z), " & -"123 (BC_1, *, control, 0), " & -"92 (BC_1, *, internal, X), " & -"24 (BC_1, A(24), output3, X, 124, 0, Z), " & -"124 (BC_1, *, control, 0), " & -"93 (BC_1, *, internal, X), " & -"25 (BC_1, A(25), output3, X, 125, 0, Z), " & -"125 (BC_1, *, control, 0), " & -"94 (BC_1, *, internal, X), " & -"26 (BC_1, A(26), output3, X, 126, 0, Z), " & -"126 (BC_1, *, control, 0), " & -"95 (BC_1, *, internal, X), " & -"27 (BC_1, A(27), output3, X, 127, 0, Z), " & -"127 (BC_1, *, control, 0), " & -"96 (BC_1, *, internal, X), " & -"28 (BC_1, A(28), output3, X, 128, 0, Z), " & -"128 (BC_1, *, control, 0), " & -"97 (BC_1, *, internal, X), " & -"29 (BC_1, A(29), output3, X, 129, 0, Z), " & -"129 (BC_1, *, control, 0), " & -"98 (BC_1, *, internal, X), " & -"30 (BC_1, A(30), output3, X, 130, 0, Z), " & -"130 (BC_1, *, control, 0), " & -"99 (BC_1, *, internal, X), " & -"31 (BC_1, A(31), output3, X, 131, 0, Z), " & -"131 (BC_1, *, control, 0), " & -"132 (BC_1, D(0), input, X), " & -"32 (BC_1, D(0), output3, X, 164, 0, Z), " & +"99 (BC_1, RESET, input, X), " & +"106 (BC_1, *, internal, X), " & +"0 (BC_1, A(0), output3, X, 138, 0, Z), " & +"138 (BC_1, *, control, 0), " & +"107 (BC_1, *, internal, X), " & +"1 (BC_1, A(1), output3, X, 139, 0, Z), " & +"139 (BC_1, *, control, 0), " & +"108 (BC_1, *, internal, X), " & +"2 (BC_1, A(2), output3, X, 140, 0, Z), " & +"140 (BC_1, *, control, 0), " & +"109 (BC_1, *, internal, X), " & +"3 (BC_1, A(3), output3, X, 141, 0, Z), " & +"141 (BC_1, *, control, 0), " & +"110 (BC_1, *, internal, X), " & +"4 (BC_1, A(4), output3, X, 142, 0, Z), " & +"142 (BC_1, *, control, 0), " & +"111 (BC_1, *, internal, X), " & +"5 (BC_1, A(5), output3, X, 143, 0, Z), " & +"143 (BC_1, *, control, 0), " & +"112 (BC_1, *, internal, X), " & +"6 (BC_1, A(6), output3, X, 144, 0, Z), " & +"144 (BC_1, *, control, 0), " & +"113 (BC_1, *, internal, X), " & +"7 (BC_1, A(7), output3, X, 145, 0, Z), " & +"145 (BC_1, *, control, 0), " & +"114 (BC_1, *, internal, X), " & +"8 (BC_1, A(8), output3, X, 146, 0, Z), " & +"146 (BC_1, *, control, 0), " & +"115 (BC_1, *, internal, X), " & +"9 (BC_1, A(9), output3, X, 147, 0, Z), " & +"147 (BC_1, *, control, 0), " & +"116 (BC_1, *, internal, X), " & +"10 (BC_1, A(10), output3, X, 148, 0, Z), " & +"148 (BC_1, *, control, 0), " & +"117 (BC_1, *, internal, X), " & +"11 (BC_1, A(11), output3, X, 149, 0, Z), " & +"149 (BC_1, *, control, 0), " & +"118 (BC_1, *, internal, X), " & +"12 (BC_1, A(12), output3, X, 150, 0, Z), " & +"150 (BC_1, *, control, 0), " & +"119 (BC_1, *, internal, X), " & +"13 (BC_1, A(13), output3, X, 151, 0, Z), " & +"151 (BC_1, *, control, 0), " & +"120 (BC_1, *, internal, X), " & +"14 (BC_1, A(14), output3, X, 152, 0, Z), " & +"152 (BC_1, *, control, 0), " & +"121 (BC_1, *, internal, X), " & +"15 (BC_1, A(15), output3, X, 153, 0, Z), " & +"153 (BC_1, *, control, 0), " & +"122 (BC_1, *, internal, X), " & +"16 (BC_1, A(16), output3, X, 154, 0, Z), " & +"154 (BC_1, *, control, 0), " & +"123 (BC_1, *, internal, X), " & +"17 (BC_1, A(17), output3, X, 155, 0, Z), " & +"155 (BC_1, *, control, 0), " & +"124 (BC_1, *, internal, X), " & +"18 (BC_1, A(18), output3, X, 156, 0, Z), " & +"156 (BC_1, *, control, 0), " & +"125 (BC_1, *, internal, X), " & +"19 (BC_1, A(19), output3, X, 157, 0, Z), " & +"157 (BC_1, *, control, 0), " & +"126 (BC_1, *, internal, X), " & +"20 (BC_1, A(20), output3, X, 158, 0, Z), " & +"158 (BC_1, *, control, 0), " & +"127 (BC_1, *, internal, X), " & +"21 (BC_1, A(21), output3, X, 159, 0, Z), " & +"159 (BC_1, *, control, 0), " & +"128 (BC_1, *, internal, X), " & +"22 (BC_1, A(22), output3, X, 160, 0, Z), " & +"160 (BC_1, *, control, 0), " & +"129 (BC_1, *, internal, X), " & +"23 (BC_1, A(23), output3, X, 161, 0, Z), " & +"161 (BC_1, *, control, 0), " & +"130 (BC_1, *, internal, X), " & +"24 (BC_1, A(24), output3, X, 162, 0, Z), " & +"162 (BC_1, *, control, 0), " & +"131 (BC_1, *, internal, X), " & +"25 (BC_1, A(25), output3, X, 163, 0, Z), " & +"163 (BC_1, *, control, 0), " & +"132 (BC_1, *, internal, X), " & +"26 (BC_1, A(26), output3, X, 164, 0, Z), " & "164 (BC_1, *, control, 0), " & -"133 (BC_1, D(1), input, X), " & -"33 (BC_1, D(1), output3, X, 165, 0, Z), " & +"133 (BC_1, *, internal, X), " & +"27 (BC_1, A(27), output3, X, 165, 0, Z), " & "165 (BC_1, *, control, 0), " & -"134 (BC_1, D(2), input, X), " & -"34 (BC_1, D(2), output3, X, 166, 0, Z), " & +"134 (BC_1, *, internal, X), " & +"28 (BC_1, A(28), output3, X, 166, 0, Z), " & "166 (BC_1, *, control, 0), " & -"135 (BC_1, D(3), input, X), " & -"35 (BC_1, D(3), output3, X, 167, 0, Z), " & +"135 (BC_1, *, internal, X), " & +"29 (BC_1, A(29), output3, X, 167, 0, Z), " & "167 (BC_1, *, control, 0), " & -"136 (BC_1, D(4), input, X), " & -"36 (BC_1, D(4), output3, X, 168, 0, Z), " & +"136 (BC_1, *, internal, X), " & +"30 (BC_1, A(30), output3, X, 168, 0, Z), " & "168 (BC_1, *, control, 0), " & -"137 (BC_1, D(5), input, X), " & -"37 (BC_1, D(5), output3, X, 169, 0, Z), " & +"137 (BC_1, *, internal, X), " & +"31 (BC_1, A(31), output3, X, 169, 0, Z), " & "169 (BC_1, *, control, 0), " & -"138 (BC_1, D(6), input, X), " & -"38 (BC_1, D(6), output3, X, 170, 0, Z), " & +"64 (BC_1, D(0), input, X), " & +"32 (BC_1, D(0), output3, X, 170, 0, Z), " & "170 (BC_1, *, control, 0), " & -"139 (BC_1, D(7), input, X), " & -"39 (BC_1, D(7), output3, X, 171, 0, Z), " & +"65 (BC_1, D(1), input, X), " & +"33 (BC_1, D(1), output3, X, 171, 0, Z), " & "171 (BC_1, *, control, 0), " & -"140 (BC_1, D(8), input, X), " & -"40 (BC_1, D(8), output3, X, 172, 0, Z), " & +"66 (BC_1, D(2), input, X), " & +"34 (BC_1, D(2), output3, X, 172, 0, Z), " & "172 (BC_1, *, control, 0), " & -"141 (BC_1, D(9), input, X), " & -"41 (BC_1, D(9), output3, X, 173, 0, Z), " & +"67 (BC_1, D(3), input, X), " & +"35 (BC_1, D(3), output3, X, 173, 0, Z), " & "173 (BC_1, *, control, 0), " & -"142 (BC_1, D(10), input, X), " & -"42 (BC_1, D(10), output3, X, 174, 0, Z), " & +"68 (BC_1, D(4), input, X), " & +"36 (BC_1, D(4), output3, X, 174, 0, Z), " & "174 (BC_1, *, control, 0), " & -"143 (BC_1, D(11), input, X), " & -"43 (BC_1, D(11), output3, X, 175, 0, Z), " & +"69 (BC_1, D(5), input, X), " & +"37 (BC_1, D(5), output3, X, 175, 0, Z), " & "175 (BC_1, *, control, 0), " & -"144 (BC_1, D(12), input, X), " & -"44 (BC_1, D(12), output3, X, 176, 0, Z), " & +"70 (BC_1, D(6), input, X), " & +"38 (BC_1, D(6), output3, X, 176, 0, Z), " & "176 (BC_1, *, control, 0), " & -"145 (BC_1, D(13), input, X), " & -"45 (BC_1, D(13), output3, X, 177, 0, Z), " & +"71 (BC_1, D(7), input, X), " & +"39 (BC_1, D(7), output3, X, 177, 0, Z), " & "177 (BC_1, *, control, 0), " & -"146 (BC_1, D(14), input, X), " & -"46 (BC_1, D(14), output3, X, 178, 0, Z), " & +"72 (BC_1, D(8), input, X), " & +"40 (BC_1, D(8), output3, X, 178, 0, Z), " & "178 (BC_1, *, control, 0), " & -"147 (BC_1, D(15), input, X), " & -"47 (BC_1, D(15), output3, X, 179, 0, Z), " & +"73 (BC_1, D(9), input, X), " & +"41 (BC_1, D(9), output3, X, 179, 0, Z), " & "179 (BC_1, *, control, 0), " & -"148 (BC_1, D(16), input, X), " & -"48 (BC_1, D(16), output3, X, 180, 0, Z), " & +"74 (BC_1, D(10), input, X), " & +"42 (BC_1, D(10), output3, X, 180, 0, Z), " & "180 (BC_1, *, control, 0), " & -"149 (BC_1, D(17), input, X), " & -"49 (BC_1, D(17), output3, X, 181, 0, Z), " & +"75 (BC_1, D(11), input, X), " & +"43 (BC_1, D(11), output3, X, 181, 0, Z), " & "181 (BC_1, *, control, 0), " & -"150 (BC_1, D(18), input, X), " & -"50 (BC_1, D(18), output3, X, 182, 0, Z), " & +"76 (BC_1, D(12), input, X), " & +"44 (BC_1, D(12), output3, X, 182, 0, Z), " & "182 (BC_1, *, control, 0), " & -"151 (BC_1, D(19), input, X), " & -"51 (BC_1, D(19), output3, X, 183, 0, Z), " & +"77 (BC_1, D(13), input, X), " & +"45 (BC_1, D(13), output3, X, 183, 0, Z), " & "183 (BC_1, *, control, 0), " & -"152 (BC_1, D(20), input, X), " & -"52 (BC_1, D(20), output3, X, 184, 0, Z), " & +"78 (BC_1, D(14), input, X), " & +"46 (BC_1, D(14), output3, X, 184, 0, Z), " & "184 (BC_1, *, control, 0), " & -"153 (BC_1, D(21), input, X), " & -"53 (BC_1, D(21), output3, X, 185, 0, Z), " & +"79 (BC_1, D(15), input, X), " & +"47 (BC_1, D(15), output3, X, 185, 0, Z), " & "185 (BC_1, *, control, 0), " & -"154 (BC_1, D(22), input, X), " & -"54 (BC_1, D(22), output3, X, 186, 0, Z), " & +"80 (BC_1, D(16), input, X), " & +"48 (BC_1, D(16), output3, X, 186, 0, Z), " & "186 (BC_1, *, control, 0), " & -"155 (BC_1, D(23), input, X), " & -"55 (BC_1, D(23), output3, X, 187, 0, Z), " & +"81 (BC_1, D(17), input, X), " & +"49 (BC_1, D(17), output3, X, 187, 0, Z), " & "187 (BC_1, *, control, 0), " & -"156 (BC_1, D(24), input, X), " & -"56 (BC_1, D(24), output3, X, 188, 0, Z), " & +"82 (BC_1, D(18), input, X), " & +"50 (BC_1, D(18), output3, X, 188, 0, Z), " & "188 (BC_1, *, control, 0), " & -"157 (BC_1, D(25), input, X), " & -"57 (BC_1, D(25), output3, X, 189, 0, Z), " & +"83 (BC_1, D(19), input, X), " & +"51 (BC_1, D(19), output3, X, 189, 0, Z), " & "189 (BC_1, *, control, 0), " & -"158 (BC_1, D(26), input, X), " & -"58 (BC_1, D(26), output3, X, 190, 0, Z), " & +"84 (BC_1, D(20), input, X), " & +"52 (BC_1, D(20), output3, X, 190, 0, Z), " & "190 (BC_1, *, control, 0), " & -"159 (BC_1, D(27), input, X), " & -"59 (BC_1, D(27), output3, X, 191, 0, Z), " & +"85 (BC_1, D(21), input, X), " & +"53 (BC_1, D(21), output3, X, 191, 0, Z), " & "191 (BC_1, *, control, 0), " & -"160 (BC_1, D(28), input, X), " & -"60 (BC_1, D(28), output3, X, 192, 0, Z), " & +"86 (BC_1, D(22), input, X), " & +"54 (BC_1, D(22), output3, X, 192, 0, Z), " & "192 (BC_1, *, control, 0), " & -"161 (BC_1, D(29), input, X), " & -"61 (BC_1, D(29), output3, X, 193, 0, Z), " & +"87 (BC_1, D(23), input, X), " & +"55 (BC_1, D(23), output3, X, 193, 0, Z), " & "193 (BC_1, *, control, 0), " & -"162 (BC_1, D(30), input, X), " & -"62 (BC_1, D(30), output3, X, 194, 0, Z), " & +"88 (BC_1, D(24), input, X), " & +"56 (BC_1, D(24), output3, X, 194, 0, Z), " & "194 (BC_1, *, control, 0), " & -"163 (BC_1, D(31), input, X), " & -"63 (BC_1, D(31), output3, X, 195, 0, Z), " & +"89 (BC_1, D(25), input, X), " & +"57 (BC_1, D(25), output3, X, 195, 0, Z), " & "195 (BC_1, *, control, 0), " & -"196 (BC_1, *, internal, X), " & -"64 (BC_1, OE, output3, X, 197, 0, Z), " & +"90 (BC_1, D(26), input, X), " & +"58 (BC_1, D(26), output3, X, 196, 0, Z), " & +"196 (BC_1, *, control, 0), " & +"91 (BC_1, D(27), input, X), " & +"59 (BC_1, D(27), output3, X, 197, 0, Z), " & "197 (BC_1, *, control, 0), " & -"198 (BC_1, *, internal, X), " & -"65 (BC_1, WE, output3, X, 199, 0, Z), " & +"92 (BC_1, D(28), input, X), " & +"60 (BC_1, D(28), output3, X, 198, 0, Z), " & +"198 (BC_1, *, control, 0), " & +"93 (BC_1, D(29), input, X), " & +"61 (BC_1, D(29), output3, X, 199, 0, Z), " & "199 (BC_1, *, control, 0), " & -"200 (BC_1, *, internal, X), " & -"66 (BC_1, CS, output3, X, 201, 0, Z), " & -"201 (BC_1, *, control, 0), " & -"67 (BC_1, RESET, input, X) " ; +"94 (BC_1, D(30), input, X), " & +"62 (BC_1, D(30), output3, X, 200, 0, Z), " & +"200 (BC_1, *, control, 0), " & +"95 (BC_1, D(31), input, X), " & +"63 (BC_1, D(31), output3, X, 201, 0, Z), " & +"201 (BC_1, *, control, 0) " ; end some_cpu ; diff --git a/jtag/src/jim/some_cpu.c b/jtag/src/jim/some_cpu.c index 513b10f5..ab807f5a 100644 --- a/jtag/src/jim/some_cpu.c +++ b/jtag/src/jim/some_cpu.c @@ -26,13 +26,22 @@ #include #include #include +#include -extern jim_bus_device_t intel_28f800b3; +#undef VERBOSE + +extern jim_bus_device_t intel_28f800b3t; jim_attached_part_t some_cpu_attached[] = { - { 0x00000000, &intel_28f800b3 }, - { 0xFFFFFFFF, NULL } + /* 1. Address offset: base offset [bytes] + * 2. Address shift: Distance between address LSB of device and CPU + * 3. Data shift: Distance between D0 of device and CPU e.g. 0, 8, 16 or 24 bits + * 4. Part: Pointer to part structure */ + + { 0x00000000, 1, 0, &intel_28f800b3t }, + + { 0xFFFFFFFF, 0, 0, NULL } /* Always end list with part == NULL */ }; #define BSR_LEN 202 @@ -44,61 +53,86 @@ void some_cpu_report_idcode(jim_device_t *dev) dev->current_dr = 1; /* IDR */ } -void some_cpu_extest(char *st, jim_device_t *dev) +void some_cpu_tck_rise(jim_device_t *dev, + int tms, int tdi, + uint8_t *shmem, size_t shmem_size ) { int i; - printf("EXTEST/%s with A=%08X, D=%08X%s%s%s\n", st, - dev->sreg[2].reg[0], dev->sreg[2].reg[1], - (dev->sreg[2].reg[2] & 1) ? ", OE":"", - (dev->sreg[2].reg[2] & 2) ? ", WE":"", - (dev->sreg[2].reg[2] & 4) ? ", CS":""); - - for(i=0; some_cpu_attached[i].part; i++) - { - jim_bus_device_t *b = ((jim_attached_part_t*)(dev->state))[i].part; - - b->access(b, dev->sreg[2].reg[0], - dev->sreg[2].reg[1], - dev->sreg[2].reg[2]); - } -} - -void some_cpu_tck_rise(jim_device_t *dev, int tms, int tdi) -{ // jim_print_tap_state(dev); switch(dev->tap_state) { case RESET: + some_cpu_report_idcode(dev); break; - case UPDATE_DR: - if(dev->current_dr == 2) + case CAPTURE_DR: + + if(dev->current_dr==2) // if(dev->sreg[0].reg[0] == 0 && dev->current_dr == 2) /* EXTEST */ { - if(dev->sreg[0].reg[0] == 0) some_cpu_extest("UPDATE_DR", dev); + uint32_t a = dev->sreg[2].reg[0]; + uint32_t d = 0; + uint32_t c = dev->sreg[2].reg[3]; + +#ifdef VERBOSE + printf("CAPTURE_DR/EXTEST\n"); +#endif + + for(i=0; some_cpu_attached[i].part; i++) + { + jim_attached_part_t *tp = &(((jim_attached_part_t*)(dev->state))[i]); + jim_bus_device_t *b = tp->part; + + /* Address decoder */ + if(tp->offset < a) + { + uint32_t as = (a - (tp->offset)) >> tp->adr_shift; + if(as < b->size) + { + d |= b->capture(b, as, c, shmem, shmem_size) << tp->data_shift; + } + } + } + + /* Store data into data "input" cells in BSR */ + dev->sreg[2].reg[2] = d; + jim_print_tap_state(dev); + }; break; - + case UPDATE_IR: + +#ifdef VERBOSE + printf("UPDATE_IR/"); +#endif + switch(dev->sreg[0].reg[0]) { case 0x0: /* EXTEST */ +#ifdef VERBOSE printf("EXTEST\n"); +#endif dev->current_dr = 2; - some_cpu_extest("UPDATE_IR", dev); break; case 0x1: /* IDCODE */ +#ifdef VERBOSE printf("IDCODE\n"); +#endif some_cpu_report_idcode(dev); break; case 0x2: /* SAMPLE */ +#ifdef VERBOSE printf("SAMPLE\n"); +#endif dev->current_dr = 2; break; case 0x3: /* BYPASS */ +#ifdef VERBOSE printf("BYPASS\n"); +#endif default: dev->current_dr = 0; /* BYPASS */ break; @@ -110,6 +144,48 @@ void some_cpu_tck_rise(jim_device_t *dev, int tms, int tdi) } } +void some_cpu_tck_fall(jim_device_t *dev, + uint8_t *shmem, size_t shmem_size ) +{ + int i; + + switch(dev->tap_state) + { + case UPDATE_DR: + + if(dev->sreg[0].reg[0] == 0 && dev->current_dr == 2) /* EXTEST */ + { + uint32_t a = dev->sreg[2].reg[0]; + uint32_t d = dev->sreg[2].reg[1]; + uint32_t c = dev->sreg[2].reg[3]; + +#ifdef VERBOSE + printf("UPDATE_DR/EXTEST\n"); +#endif + + for(i=0; some_cpu_attached[i].part; i++) + { + jim_attached_part_t *tp = &(((jim_attached_part_t*)(dev->state))[i]); + jim_bus_device_t *b = tp->part; + + /* Address decoder */ + if(tp->offset < a) + { + uint32_t as = (a - (tp->offset)) >> tp->adr_shift; + if(as < b->size) + { + b->update(b, as, d >> tp->data_shift, c, shmem, shmem_size); + } + } + } + }; + break; + + default: + break; + } +} + void some_cpu_free(jim_device_t *dev) { int i; @@ -121,6 +197,7 @@ void some_cpu_free(jim_device_t *dev) { jim_bus_device_t *b = ((jim_attached_part_t*)(dev->state))[i].part; if(b->free != NULL) b->free(b); + free(b); } free(dev->state); } @@ -134,7 +211,10 @@ jim_device_t *some_cpu(void) if(dev) { - dev->state = malloc(sizeof(some_cpu_attached)); + /* Allocate memory for copies of the original structure for dynamic + * modifications (e.g. if bus width changes because of some signal) */ + + dev->state = malloc(sizeof(some_cpu_attached)); if(!dev->state) { free(dev); @@ -144,16 +224,28 @@ jim_device_t *some_cpu(void) { int i; dev->tck_rise = some_cpu_tck_rise; + dev->tck_fall = some_cpu_tck_fall; dev->dev_free = some_cpu_free; memcpy(dev->state, some_cpu_attached, sizeof(some_cpu_attached)); - for(i=0;some_cpu_attached[i].part;i++) + + for(i=0;some_cpu_attached[i].part;i++) { - jim_bus_device_t *b = ((jim_attached_part_t*)(dev->state))[i].part; - b->init(b); + jim_bus_device_t **b = &(((jim_attached_part_t*)(dev->state))[i].part); + *b = malloc(sizeof(jim_bus_device_t)); + if(*b == NULL) break; + memcpy(*b, some_cpu_attached[i].part, sizeof(jim_bus_device_t)); + (*b)->init(*b); + }; + + if(some_cpu_attached[i].part) /* loop broken; failed to malloc all parts */ + { + for(i--;i>=0;i--) free(((jim_attached_part_t*)(dev->state))[i].part); + free(dev->state); + free(dev); + dev = NULL; } } } - return dev; } diff --git a/jtag/src/jim/tap.c b/jtag/src/jim/tap.c index 97e0135f..2c621910 100644 --- a/jtag/src/jim/tap.c +++ b/jtag/src/jim/tap.c @@ -52,7 +52,8 @@ const tap_state_t next_tap_state[16][2] = void jim_print_sreg(shift_reg_t *r) { - printf("%08X", r->reg[0]); + int i; + for(i=(r->len+31)/32; i>=0; i--) printf(" %08X", r->reg[i]); } void jim_print_tap_state(jim_device_t *dev) @@ -80,7 +81,7 @@ void jim_print_tap_state(jim_device_t *dev) printf("_DR"); if(dev->current_dr != 0) { - printf("="); + printf("(%d)=", dev->current_dr); jim_print_sreg(&dev->sreg[dev->current_dr]); } }; @@ -118,7 +119,7 @@ void jim_tck_rise(jim_state_t *s, int tms, int tdi) dev_tdi = (dev->prev != NULL) ? dev->prev->tdo : tdi; - if(dev->tck_rise != NULL) dev->tck_rise(dev, tms, dev_tdi); + if(dev->tck_rise != NULL) dev->tck_rise(dev, tms, dev_tdi, s->shmem, s->shmem_size); if(dev->tap_state & 8) { @@ -181,7 +182,7 @@ void jim_tck_fall(jim_state_t *s) { dev->tdo = dev->tdo_buffer; - if(dev->tck_fall != NULL) dev->tck_fall(dev); + if(dev->tck_fall != NULL) dev->tck_fall(dev, s->shmem, s->shmem_size); } } @@ -246,6 +247,21 @@ jim_state_t *jim_init(void) return NULL; }; + s->shmem_size = (1<<20)*16; /* 16 MByte */ + s->shmem = malloc(s->shmem_size); + + if(s->shmem != NULL) + { + memset(s->shmem, 0xFF, s->shmem_size); + printf("Allocated %zd bytes for device memory simulation.\n", s->shmem_size); + } + else + { + free(s); + printf("Out of memory!\n"); + return NULL; + } + s->trst = 0; s->last_device_in_chain = some_cpu(); @@ -256,6 +272,8 @@ jim_state_t *jim_init(void) else { printf("Out of memory!\n"); + free(s->shmem); + free(s); return NULL; } return s; @@ -282,7 +300,7 @@ void jim_free(jim_state_t *s) } s->last_device_in_chain = NULL; - + free(s->shmem); free(s); }