├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── guide.pdf ├── spi.h ├── tjtag.c ├── tjtag.h └── wiring.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | *.[ao] 2 | *.swp 3 | tjtag 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS += -Wall -O2 2 | 3 | WRT54GMEMOBJS = tjtag.o 4 | 5 | all: tjtag 6 | 7 | wrt54g: $(WRT54GMEMOBJS) 8 | gcc $(CFLAGS) -o $@ $(WRT54GMEMOBJS) 9 | 10 | pi: CFLAGS += -D RASPPI 11 | pi: all 12 | 13 | clean: 14 | rm -rf *.o tjtag 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tjtag-pi is a fork of [tjtag][] with support for [Raspberry Pi][pi] 2 | which eliminates the need for a PC with parallel port. See [acidice333](https://github.com/acidice333/tjtag-pi)'s fork for running on RPi 3. 3 | 4 | WARNING 5 | ======= 6 | 7 | Be warned that incorrect usage can lead to a point of no return 8 | situation. Before you do anything besides what is described here, please 9 | do research on how to use this tool. A good starting point is the 10 | excellent and cautionary `guide.pdf` written by the HairyDairyMaid, the 11 | original author. Always backup before flashing. 12 | 13 | Requirements 14 | ============ 15 | 16 | * A Raspberry Pi (I've only tested model B as of late 2013) 17 | * [Dual female jumper wires][jumper] to connect GPIO pins to WRT 18 | * Pins soldered on the JTAG header on WRT 19 | * Beverege to enjoy afterward 20 | 21 | Setup 22 | ===== 23 | 24 | 1. Hook up the two boards as per the diagram in `wiring.jpg` 25 | 2. Power up your WRT 26 | 3. Checkout the code, compile and run it 27 | 28 | $ cd ~ 29 | $ git clone git@github.com:oxplot/tjtag-pi.git 30 | $ cd tjtag-pi 31 | $ make pi 32 | $ ./tjtag -probeonly 33 | 34 | If it gets stuck, try using `/noemw` option. 35 | 36 | If at this point, your SoC and flash is recognized, you're all set. 37 | Enjoy your beverage and look for an appropriate guide that explains how 38 | to use tjtag to revive/upgrade your router's firmware. 39 | 40 | Notes 41 | ===== 42 | 43 | * If you have issues with reliability of your connection, you can slow 44 | down the speed of _tjtag_ by using `/delay:N` command line option. 45 | `N` is the amount of time to delay flipping the clock signal. The 46 | higher the value, the slower the transfer rate. 47 | * Due to bit-banging nature of the operation of tjtag, various things 48 | affect the transfer speed. The one with most degrading effect is the 49 | progress output. Therefore it is recommended to use `/silent` command 50 | line option and redirect outputs to `/dev/null` (ie using 51 | `&> /dev/null`), after having made sure everything works OK. 52 | 53 | [jumper]: http://www.seeedstudio.com/depot/1-pin-dualfemale-jumper-wire-100mm-50pcs-pack-p-260.html?cPath=44 54 | [tjtag]: http://sourceforge.net/projects/tjtag/ 55 | [pi]: http://www.raspberrypi.org/ 56 | -------------------------------------------------------------------------------- /guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oxplot/tjtag-pi/60da15b288ab4b1d9edb42c40227392a171bdcfb/guide.pdf -------------------------------------------------------------------------------- /spi.h: -------------------------------------------------------------------------------- 1 | // for SPI FLASH 2 | 3 | #define AR5315_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ 4 | /* GPIO */ 5 | #define AR5315_GPIO_DI (AR5315_DSLBASE + 0x0088) 6 | #define AR5315_GPIO_DO (AR5315_DSLBASE + 0x0090) 7 | #define AR5315_GPIO_CR (AR5315_DSLBASE + 0x0098) 8 | #define AR5315_GPIO_INT (AR5315_DSLBASE + 0x00a0) 9 | 10 | 11 | #define AR531XPLUS_SPI_READ 0x1fc00000 12 | #define AR531XPLUS_SPI_MMR 0x11300000 13 | #define AR531XPLUS_SPI_MMR_SIZE 12 14 | #define AR531XPLUS_SPI_CTL 0x00 15 | #define AR531XPLUS_SPI_OPCODE 0x04 16 | #define AR531XPLUS_SPI_DATA 0x08 17 | 18 | #define BRCM_SPI_READ 0x1fc00000 19 | #define BRCM_SPI_MMR 0x00000000 20 | #define BRCM_SPI_MMR_SIZE 0 21 | #define BRCM_SPI_CTL 0x18000040 22 | #define BRCM_FLASHADDRESS 0x18000044 23 | #define BRCM_SPI_DATA 0x18000048 24 | #define BRCM_SPI_OPCODE 0x18000044 25 | 26 | #define STM_PAGE_SIZE 256 27 | 28 | #define STM_8MBIT_SIGNATURE 0x13 29 | #define STM_M25P80_BYTE_COUNT 1048576 30 | #define STM_M25P80_SECTOR_COUNT 16 31 | #define STM_M25P80_SECTOR_SIZE 0x10000 32 | 33 | #define STM_16MBIT_SIGNATURE 0x14 34 | #define STM_M25P16_BYTE_COUNT 2097152 35 | #define STM_M25P16_SECTOR_COUNT 32 36 | #define STM_M25P16_SECTOR_SIZE 0x10000 37 | 38 | #define STM_32MBIT_SIGNATURE 0x15 39 | #define STM_M25P32_BYTE_COUNT 4194304 40 | #define STM_M25P32_SECTOR_COUNT 64 41 | #define STM_M25P32_SECTOR_SIZE 0x10000 42 | 43 | #define STM_64MBIT_SIGNATURE 0x16 // guess work blah!! 44 | 45 | #define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT 46 | #define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT 47 | #define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE 48 | #define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT 49 | #define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT 50 | #define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE 51 | #define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT 52 | #define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT 53 | #define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE 54 | 55 | #define AR_SPI_CTL_START 0x00000100 56 | #define AR_SPI_CTL_BUSY 0x00010000 57 | 58 | //#define SPI_CTL_START 0x00000100 59 | //#define SPI_CTL_BUSY 0x00010000 60 | 61 | #define BRCM_SPI_CTL_START 0x80000000 62 | #define BRCM_SPI_CTL_BUSY 0x80000000 63 | 64 | #define SPI_CTL_TXCNT_MASK 0x0000000f 65 | #define SPI_CTL_RXCNT_MASK 0x000000f0 66 | #define SPI_CTL_TX_RX_CNT_MASK 0x000000ff 67 | #define SPI_CTL_SIZE_MASK 0x00060000 68 | #define SPI_CTL_CLK_SEL_MASK 0x03000000 69 | #define SPI_OPCODE_MASK 0x000000ff 70 | 71 | /* 72 | * ST Microelectronics Opcodes for Serial Flash 73 | */ 74 | 75 | #define STM_OP_WR_ENABLE 0x06 /* Write Enable */ 76 | #define STM_OP_WR_DISABLE 0x04 /* Write Disable */ 77 | #define STM_OP_RD_STATUS 0x05 /* Read Status */ 78 | #define STM_OP_WR_STATUS 0x01 /* Write Status */ 79 | #define STM_OP_RD_DATA 0x03 /* Read Data */ 80 | #define STM_OP_FAST_RD_DATA 0x0b /* Fast Read Data */ 81 | #define STM_OP_PAGE_PGRM 0x02 /* Page Program */ 82 | #define STM_OP_SECTOR_ERASE 0xd8 /* Sector Erase */ 83 | #define STM_OP_BULK_ERASE 0xc7 /* Bulk Erase */ 84 | #define STM_OP_DEEP_PWRDOWN 0xb9 /* Deep Power-Down Mode */ 85 | #define STM_OP_RD_SIG 0xab /* Read Electronic Signature */ 86 | #define STM_OP_RD_ID 0x9f /* Read Identification */ 87 | 88 | #define BCM_STM_OP_WR_ENABLE 0x0006 /* Write Enable */ 89 | #define BCM_STM_OP_RD_STATUS 0x0105 /* Read Status */ 90 | #define BCM_STM_OP_PAGE_PGRM 0x0402 /* Page Program */ 91 | #define BCM_STM_OP_SECTOR_ERASE 0x02d8 /* Sector Erase */ 92 | #define BCM_STM_OP_RD_ID 0x049f 93 | 94 | #define SPI_WRITE_ENABLE 0 95 | #define SPI_WRITE_DISABLE 1 96 | #define SPI_RD_STATUS 2 97 | #define SPI_WR_STATUS 3 98 | #define SPI_RD_DATA 4 99 | #define SPI_FAST_RD_DATA 5 100 | #define SPI_PAGE_PROGRAM 6 101 | #define SPI_SECTOR_ERASE 7 102 | #define SPI_BULK_ERASE 8 103 | #define SPI_DEEP_PWRDOWN 9 104 | #define SPI_RD_SIG 10 105 | #define SPI_RD_ID 11 106 | 107 | #define BCM_SPI_WRITE_ENABLE 12 108 | #define BCM_SPI_RD_STATUS 13 109 | #define BCM_SPI_PAGE_PROGRAM 14 110 | #define BCM_SPI_SECTOR_ERASE 15 111 | #define BCM_SPI_RD_ID 16 112 | #define SPI_MAX_OPCODES 17 113 | 114 | #define STM_STATUS_WIP 0x01 /* Write-In-Progress */ 115 | #define STM_STATUS_WEL 0x02 /* Write Enable Latch */ 116 | #define STM_STATUS_BP0 0x04 /* Block Protect 0 */ 117 | #define STM_STATUS_BP1 0x08 /* Block Protect 1 */ 118 | #define STM_STATUS_BP2 0x10 /* Block Protect 2 */ 119 | #define STM_STATUS_SRWD 0x80 /* Status Register Write Disable */ 120 | 121 | #define SPI_STATUS_WIP STM_STATUS_WIP 122 | 123 | #define FLASH_1MB 1 124 | #define FLASH_2MB 2 125 | #define FLASH_4MB 3 126 | #define MAX_FLASH 4 127 | 128 | #define SF_PAGESIZE 528 /* bytes */ 129 | 130 | 131 | #define byteSwap_32(value) \ 132 | (((((uint32_t)value)<<24) & 0xFF000000) | \ 133 | ((((uint32_t)value)<< 8) & 0x00FF0000) | \ 134 | ((((uint32_t)value)>> 8) & 0x0000FF00) | \ 135 | ((((uint32_t)value)>>24) & 0x000000FF)) 136 | 137 | struct opcodes 138 | { 139 | uint16_t code; 140 | uint8_t tx_cnt; 141 | uint8_t rx_cnt; 142 | } 143 | stm_opcodes[] = 144 | { 145 | {STM_OP_WR_ENABLE, 1, 0}, 146 | {STM_OP_WR_DISABLE, 1, 0}, 147 | {STM_OP_RD_STATUS, 1, 1}, 148 | {STM_OP_WR_STATUS, 1, 0}, 149 | {STM_OP_RD_DATA, 4, 4}, 150 | {STM_OP_FAST_RD_DATA, 1, 0}, 151 | {STM_OP_PAGE_PGRM, 8, 0}, 152 | {STM_OP_SECTOR_ERASE, 4, 0}, 153 | {STM_OP_BULK_ERASE, 1, 0}, 154 | {STM_OP_DEEP_PWRDOWN, 1, 0}, 155 | {STM_OP_RD_SIG, 4, 1}, 156 | {STM_OP_RD_ID, 1, 3}, 157 | 158 | {BCM_STM_OP_WR_ENABLE, 1, 0}, 159 | {BCM_STM_OP_RD_STATUS, 1, 1}, 160 | {BCM_STM_OP_PAGE_PGRM, 8, 0}, 161 | {BCM_STM_OP_SECTOR_ERASE, 4, 0}, 162 | {BCM_STM_OP_RD_ID, 1, 3} 163 | 164 | }; 165 | 166 | uint32_t spiflash_sendcmd(int op); 167 | 168 | /* Atmel Opcodes AT45DB161 */ 169 | 170 | #define SF_PAGE_READ 0x52 171 | #define SF_BUFFER1_READ 0x54 172 | #define SF_BUFFER2_READ 0x56 173 | #define SF_PAGE_CACHE1 0x53 174 | #define SF_PAGE_CACHE2 0x55 175 | #define SF_PAGE_COMPARE1 0x60 176 | #define SF_PAGE_COMPARE2 0x61 177 | #define SF_BUFFER1_WRITE 0x84 178 | #define SF_BUFFER2_WRITE 0x87 179 | #define SF_BUFFER1_FLUSH_PERASE 0x83 180 | #define SF_BUFFER2_FLUSH_PERASE 0x86 181 | #define SF_BUFFER1_FLUSH 0x88 182 | #define SF_BUFFER2_FLUSH 0x89 183 | #define SF_PAGE_ERASE 0x81 184 | #define SF_BLOCK_ERASE 0x50 185 | #define SF_PAGE_PROGRAM1 0x82 186 | #define SF_PAGE_PROGRAM2 0x85 187 | #define SF_PAGE_REWRITE1 0x58 188 | #define SF_PAGE_REWRITE2 0x59 189 | #define SF_AT_READ_STATUS 0x57 190 | 191 | /* End of Atmel Opcodes and Defines */ 192 | 193 | 194 | /* flashcontrol action+opcodes for Atmel flashes */ 195 | #define SFLASH_AT_READ 0x07e8 196 | #define SFLASH_AT_PAGE_READ 0x07d2 197 | #define SFLASH_AT_BUF1_READ 198 | #define SFLASH_AT_BUF2_READ 199 | #define SFLASH_AT_STATUS 0x01d7 200 | #define SFLASH_AT_BUF1_WRITE 0x0384 201 | #define SFLASH_AT_BUF2_WRITE 0x0387 202 | #define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 203 | #define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 204 | #define SFLASH_AT_BUF1_PROGRAM 0x0288 205 | #define SFLASH_AT_BUF2_PROGRAM 0x0289 206 | #define SFLASH_AT_PAGE_ERASE 0x0281 207 | #define SFLASH_AT_BLOCK_ERASE 0x0250 208 | #define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 209 | #define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 210 | #define SFLASH_AT_BUF1_LOAD 0x0253 211 | #define SFLASH_AT_BUF2_LOAD 0x0255 212 | #define SFLASH_AT_BUF1_COMPARE 0x0260 213 | #define SFLASH_AT_BUF2_COMPARE 0x0261 214 | #define SFLASH_AT_BUF1_REPROGRAM 0x0258 215 | #define SFLASH_AT_BUF2_REPROGRAM 0x0259 216 | 217 | /* Status register bits for Atmel flashes */ 218 | 219 | /* Status bits (MSB order) 220 | */ 221 | 222 | 223 | 224 | 225 | #define SF_PAGESIZE 528 /* bytes */ 226 | /* 227 | #ifdef AT45DB161B 228 | #define DF_DENSITY_MBIT 16 229 | #define DF_PAGES 4096 230 | #define DF_BYTES_PER_PAGE 528 231 | #define DF_PAGE_ADDRESS_BITS 10 232 | #define DF_NUMBER_OF_BUFFERS 2 233 | #endif 234 | */ 235 | /*void dfBlockErase(u16 blockAddr) 236 | { 237 | // assert chip select 238 | cbi(DF_CS_PORT,DF_CS_PIN); 239 | 240 | // issue the command 241 | spiTransferByte(DF_CMD_BLOCK_ERASE); 242 | spiTransferByte((u08)(blockAddr >> (16 - DF_PAGE_ADDRESS_BITS))); 243 | spiTransferByte((u08)(blockAddr << (DF_PAGE_ADDRESS_BITS - 5))); 244 | spiTransferByte(0x00); 245 | 246 | // release chip select 247 | sbi(DF_CS_PORT,DF_CS_PIN); 248 | 249 | // wait until transfer finished 250 | while(!(dfStatusRegRead() & (1< 6 | // Copyright (C) 2004 William "Bill" Henderson (a.k.a. Tornado) 7 | // 8 | // 9 | // Copyright (C) 2013 Mansour Behabadi 10 | // 11 | // This program is free software; you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published by 13 | // the Free Software Foundation; either version 2 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License along 22 | // with this program; if not, write to the Free Software Foundation, Inc., 23 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | 25 | // Default is Compile for Linux (both #define's below should be commented out) 26 | //#define WINDOWS_VERSION // uncomment only this for Windows Compile / MS Visual C Compiler 27 | //#define __FreeBSD__ // uncomment only this for FreeBSD 28 | 29 | #ifdef WINDOWS_VERSION 30 | #include // Only for Windows Compile 31 | #define strcasecmp stricmp 32 | #define strncasecmp strnicmp 33 | #include 34 | #define _CRT_SECURE_NO_WARNINGS 35 | #endif 36 | 37 | #ifdef WINDOWS_VERSION 38 | #define tnano(seconds) Sleep((seconds) / 1000000) 39 | #define tmicro(seconds) Sleep((seconds) * 1000) 40 | /* Windows sleep is milliseconds, time/1000000 gives us nanoseconds */ 41 | #else 42 | //ulseep is in microseconds 43 | #define tnano(seconds) sleep((seconds) / 1000000000) 44 | #define tmicro(seconds) usleep(seconds) 45 | #endif 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include "tjtag.h" 57 | #include "spi.h" 58 | 59 | #define TRUE 1 60 | #define FALSE 0 61 | 62 | #ifdef RASPPI 63 | // I/O access 64 | volatile unsigned *gpio; 65 | 66 | #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) 67 | #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) 68 | #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) 69 | 70 | #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 71 | #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 72 | #define GPIO_GET *(gpio+0xd) // get bits 73 | #endif 74 | 75 | static unsigned int ctrl_reg; 76 | volatile unsigned int dcounter; 77 | 78 | int pfd; 79 | int instruction_length; 80 | int issue_reset = 1; 81 | int issue_enable_mw = 1; 82 | int issue_watchdog = 1; 83 | int issue_break = 1; 84 | int issue_erase = 1; 85 | int issue_timestamp = 1; 86 | int issue_reboot = 0; 87 | int force_dma = 0; 88 | int force_nodma = 0; 89 | int selected_fc = 0; 90 | unsigned int selected_window = 0; 91 | unsigned int selected_start = 0; 92 | unsigned int selected_length = 0; 93 | int custom_options = 0; 94 | int silent_mode = 0; 95 | int skipdetect = 0; 96 | int instrlen = 0; 97 | int wiggler = 0; 98 | int speedtouch = 0; 99 | int DEBUG = 0; 100 | int Flash_DEBUG = 0; 101 | int probe_options = 0; 102 | 103 | 104 | unsigned int flash_size = 0; 105 | int block_total = 0; 106 | unsigned int block_addr = 0; 107 | unsigned int cmd_type = 0; 108 | int ejtag_version = 0; 109 | int bypass = 0; 110 | int USE_DMA = 0; 111 | 112 | 113 | char flash_part[128]; 114 | unsigned int blocks[1024]; 115 | 116 | char AREA_NAME[128]; 117 | unsigned int AREA_START; 118 | unsigned int AREA_LENGTH; 119 | unsigned int FLASH_MEMORY_START; 120 | unsigned int vendid; 121 | unsigned int devid; 122 | 123 | unsigned int data_register; 124 | unsigned int address_register; 125 | unsigned int proc_id; 126 | unsigned int xbit = 0; 127 | unsigned int delay = 0; 128 | unsigned int bcmproc = 0; 129 | unsigned int swap_endian=0; 130 | unsigned int bigendian=0; 131 | 132 | 133 | unsigned int spi_flash_read; 134 | unsigned int spi_flash_mmr; 135 | unsigned int spi_flash_mmr_size; 136 | unsigned int spi_flash_ctl; 137 | unsigned int spi_flash_opcode; 138 | unsigned int spi_flash_data; 139 | unsigned int spi_ctl_start; 140 | unsigned int spi_ctl_busy; 141 | 142 | #define CID_ID_MASK 0x0000ffff 143 | 144 | struct STAT_REG_BITS p; 145 | 146 | typedef struct _processor_chip_type 147 | { 148 | unsigned int chip_id; // Processor Chip ID 149 | int instr_length; // EJTAG Instruction Length 150 | char* chip_descr; // Processor Chip Description 151 | } processor_chip_type; 152 | 153 | processor_chip_type processor_chip_list[] = 154 | { 155 | { 0x0471017F, 5, "Broadcom BCM4702 Rev 1 CPU" }, 156 | { 0x9470417F, 8, "Broadcom BCM4704 KPBG Rev 9 CPU"}, // Tornado WRT150N 157 | { 0x0470417F, 8, "Broadcom BCM4704 Rev 8 CPU" }, // BCM4704 chip (used in the WRTSL54GS units) 158 | { 0x1471217F, 8, "Broadcom BCM4712 Rev 1 CPU" }, 159 | { 0x2471217F, 8, "Broadcom BCM4712 Rev 2 CPU" }, 160 | { 0x1471617F, 8, "Broadcom BCM4716 Rev 1 CPU" }, // Eko BCM4718A1KFBG 161 | { 0x0478517F, 8, "Broadcom BCM4785 Rev 1 CPU" }, // Tornado WRT350N 162 | { 0x0535017F, 8, "Broadcom BCM5350 Rev 1 CPU" }, 163 | { 0x0535217F, 8, "Broadcom BCM5352 Rev 1 CPU" }, 164 | { 0x1535417F, 8, "Broadcom BCM5354 KFBG Rev 1 CPU" }, // Tornado - WRT54G GV8/GSV7 165 | { 0x2535417F, 8, "Broadcom BCM5354 KFBG Rev 2 CPU" }, // Tornado - Gv8/GSv7 166 | { 0x3535417F, 8, "Broadcom BCM5354 KFBG Rev 3 CPU" }, // Tornado - WRG54G2 167 | { 0x0334517F, 5, "Broadcom BCM3345 KPB Rev 1 CPU" }, // Eko QAMLink BCM3345 KPB SB4200 168 | { 0x0536517F, 8, "Broadcom BCM5365 Rev 1 CPU" }, // BCM5365 Not Completely Verified Yet 169 | { 0x1536517F, 8, "Broadcom BCM5365 Rev 1 CPU" }, // Eko....ASUS WL 500 G Deluxe 170 | { 0x0634517F, 5, "Broadcom BCM6345 Rev 1 CPU" }, // BCM6345 Not Completely Verified Yet 171 | { 0x0634817F, 5, "Broadcom BCM6348 Rev 1 CPU" }, 172 | { 0x0633817F, 5, "Broadcom BCM6338 Rev 1 CPU" }, // Speedtouch 173 | { 0x0635817F, 5, "Broadcom BCM6358 Rev 1 CPU" }, // brjtag Fully Tested 174 | { 0x0636817F, 5, "Broadcom BCM6368 Rev 1 CPU" }, // brjtag 175 | { 0x1432117F, 5, "Broadcom BCM4321 RADIO STOP" }, // Radio JP3 on a WRT300N V1.1 176 | { 0x3432117F, 5, "Broadcom BCM4321L RADIO STOP"}, // EKO Radio on WRT300n 177 | { 0x0000100F, 5, "TI AR7 TNETD7x00 Rev 1 CPU" }, // Verified for Linksys ADSL2MUE, same code for 7200 and 7300 chips 178 | { 0x102002E1, 5, "BRECIS MSP2007-CA-A1 CPU" }, // BRECIS chip - Not Completely Verified Yet 179 | { 0x0B52D02F, 5, "TI TNETV1060GDW CPU" }, // Fox WRTP54G 180 | { 0x00217067, 5, "Linkstation 2 with RISC K4C chip" }, // Not verified 181 | { 0x00000001, 5, "Atheros AR531X/231X CPU" }, // WHR-HP-AG108 182 | { 0x19277013, 7, "XScale IXP42X 266mhz" }, // GW2348-2 Eko Gateworks Avila GW234X (IXP42X 266MHz) BE 183 | { 0x19275013, 7, "XScale IXP42X 400mhz" }, 184 | { 0x19274013, 7, "XScale IXP42X 533mhz" }, 185 | { 0x10940027, 4, "ARM 940T"}, // Eko Linksys BEFSX41 186 | { 0x07926041, 4, "Marvell Feroceon 88F5181" }, 187 | { 0x1438000D, 5, "LX4380"}, 188 | { 189 | 0, 0, 0 190 | } 191 | }; 192 | 193 | 194 | typedef struct _flash_area_type 195 | { 196 | unsigned int chip_size; 197 | char* area_name; 198 | unsigned int area_start; 199 | unsigned int area_length; 200 | } flash_area_type; 201 | 202 | 203 | flash_area_type flash_area_list[] = 204 | { 205 | //--------- ---------- ----------- ------------ 206 | //chip_size area_name area_start area_length 207 | //--------- ---------- ----------- ------------ 208 | { size1MB, "CFE", 0x1FC00000, 0x40000 }, 209 | { size2MB, "CFE", 0x1FC00000, 0x40000 }, 210 | { size4MB, "CFE", 0x1FC00000, 0x40000 },//256Kb 211 | { size8MB, "CFE", 0x1C000000, 0x40000 }, 212 | { size16MB, "CFE", 0x1F000000, 0x40000 }, //tornado - for alice 213 | 214 | { size8MB, "AR-CFE", 0xA8000000, 0x40000 }, 215 | { size16MB, "AR-CFE", 0xA8000000, 0x40000 }, 216 | 217 | 218 | { size1MB, "CFE128", 0x1FC00000, 0x20000 }, 219 | { size2MB, "CFE128", 0x1FC00000, 0x20000 }, 220 | { size4MB, "CFE128", 0x1FC00000, 0x20000 },//128Kb 221 | { size8MB, "CFE128", 0x1C000000, 0x20000 }, 222 | { size16MB, "CFE128", 0x1C000000, 0x20000 }, 223 | 224 | { size1MB, "CF1", 0x1FC00000, 0x2000 }, 225 | { size2MB, "CF1", 0x1FC00000, 0x2000 }, 226 | { size4MB, "CF1", 0x1FC00000, 0x2000 },//8Kb 227 | { size8MB, "CF1", 0x1C000000, 0x2000 }, 228 | { size16MB, "CF1", 0x1C000000, 0x2000 }, 229 | 230 | { size1MB, "KERNEL", 0x1FC40000, 0xB0000 }, 231 | { size2MB, "KERNEL", 0x1FC40000, 0x1B0000 }, 232 | { size4MB, "KERNEL", 0x1FC40000, 0x3B0000 },//3776Kb 233 | { size8MB, "KERNEL", 0x1C040000, 0x7A0000 }, 234 | { size16MB, "KERNEL", 0x1C040000, 0x7A0000 }, 235 | { size8MB, "AR-KERNEL", 0xA8040000, 0x7A0000 }, 236 | { size16MB, "AR-KERNEL", 0xA8040000, 0x7A0000 }, 237 | 238 | { size1MB, "NVRAM", 0x1FCF0000, 0x10000 }, 239 | { size2MB, "NVRAM", 0x1FDF0000, 0x10000 }, 240 | { size4MB, "NVRAM", 0x1FFF0000, 0x10000 },//64kb 241 | { size8MB, "NVRAM", 0x1C7E0000, 0x20000 }, 242 | { size16MB, "NVRAM", 0x1C7E0000, 0x20000 }, 243 | 244 | { size8MB, "AR-NVRAM", 0xA87E0000, 0x20000 }, 245 | { size16MB, "AR-NVRAM", 0xA87E0000, 0x20000 }, 246 | 247 | { size2MB, "WGRV9NVRAM", 0x1FDFC000, 0x4000 }, 248 | { size2MB, "WGRV9BDATA", 0x1FDFB000, 0x1000 }, 249 | { size4MB, "WGRV8BDATA", 0x1FFE0000, 0x10000 },//64kb 250 | 251 | { size1MB, "WHOLEFLASH", 0x1FC00000, 0x100000 }, 252 | { size2MB, "WHOLEFLASH", 0x1FC00000, 0x200000 }, 253 | { size4MB, "WHOLEFLASH", 0x1FC00000, 0x400000 },//4Mb 254 | { size8MB, "WHOLEFLASH", 0x1C000000, 0x800000 }, 255 | // { size16MB, "WHOLEFLASH", 0x1C000000, 0x1000000 }, 256 | { size16MB, "WHOLEFLASH", 0x1F000000, 0x1000000 }, 257 | { size8MB, "AR-WHOLEFLASH", 0xA8000000, 0x800000 }, 258 | { size16MB, "AR-WHOLEFLASH", 0xA8000000, 0x1000000 }, 259 | 260 | { size1MB, "BSP", 0x1FC00000, 0x50000 }, 261 | { size2MB, "BSP", 0x1FC00000, 0x50000 }, 262 | { size4MB, "BSP", 0x1FC00000, 0x50000 }, 263 | { size8MB, "BSP", 0x1C000000, 0x50000 }, 264 | { size16MB, "BSP", 0x1C000000, 0x50000 }, 265 | 266 | { size8MB, "AR-BSP", 0xA8000000, 0x50000 }, 267 | { size16MB, "AR-BSP", 0xA8000000, 0x50000 }, 268 | 269 | { size1MB, "RED", 0x50000000, 0x50000 }, 270 | { size2MB, "RED", 0x50000000, 0x50000 }, 271 | { size4MB, "RED", 0x50000000, 0x50000 }, 272 | { size8MB, "AR-RED", 0xA8000000, 0x30000 }, 273 | { size8MB, "RED", 0x50000000, 0x50000 }, 274 | { size16MB, "RED", 0x50000000, 0x50000 }, 275 | 276 | /* extras for Ti AR7 */ 277 | { size1MB, "MTD2", 0x90000000, 0x10000 }, 278 | { size2MB, "MTD2", 0x90000000, 0x10000 }, 279 | { size4MB, "MTD2", 0x90000000, 0x10000 }, 280 | 281 | { size1MB, "MTD3", 0x90010000, 0x10000 },// only for pspboot, its at the other end for adam2 282 | { size2MB, "MTD3", 0x90010000, 0x10000 }, 283 | { size4MB, "MTD3", 0x90010000, 0x10000 }, 284 | 285 | { size1MB, "MTD4", 0x90020000, 0xE0000 }, 286 | { size2MB, "MTD4", 0x90020000, 0x1E0000 }, 287 | { size4MB, "MTD4", 0x90020000, 0x3E0000 }, 288 | 289 | { size1MB, "FULL", 0x90020000, 0x100000 }, 290 | { size2MB, "FULL", 0x90020000, 0x200000 }, 291 | { size4MB, "FULL", 0x90020000, 0x400000 }, 292 | 293 | { 0, 0, 0, 0 } 294 | }; 295 | 296 | 297 | typedef struct _flash_chip_type 298 | { 299 | unsigned int vendid; // Manufacturer Id 300 | unsigned int devid; // Device Id 301 | unsigned int flash_size; // Total size in MBytes 302 | unsigned int cmd_type; // Device CMD TYPE 303 | char* flash_part; // Flash Chip Description 304 | unsigned int region1_num; // Region 1 block count 305 | unsigned int region1_size; // Region 1 block size 306 | unsigned int region2_num; // Region 2 block count 307 | unsigned int region2_size; // Region 2 block size 308 | unsigned int region3_num; // Region 3 block count 309 | unsigned int region3_size; // Region 3 block size 310 | unsigned int region4_num; // Region 4 block count 311 | unsigned int region4_size; // Region 4 block size 312 | } flash_chip_type; 313 | 314 | 315 | flash_chip_type flash_chip_list[] = 316 | { 317 | /* AMD, Spansion */ 318 | { 0x00C2, 0x22DA, size1MB, CMD_TYPE_AMD, "MX29LV800BTC 512kx16 TopB (1MB)" ,15,size32K, 1,size16K, 2,size4K, 1,size8K }, 319 | { 0x00C2, 0x225B, size1MB, CMD_TYPE_AMD, "MX29LV800BTC 512kx16 BotB (1MB)" ,1,size8K, 2,size4K, 1,size16K, 15,size32K }, 320 | 321 | { 0x0001, 0x2249, size2MB, CMD_TYPE_AMD, "AMD 29lv160DB 1Mx16 BotB (2MB)" ,1,size16K, 2,size8K, 1,size32K, 31,size64K }, /* bypass */ 322 | { 0x0001, 0x22c4, size2MB, CMD_TYPE_AMD, "AMD 29lv160DT 1Mx16 TopB (2MB)" ,31,size64K, 1,size32K, 2,size8K, 1,size16K }, 323 | { 0x007F, 0x2249, size2MB, CMD_TYPE_AMD, "EON EN29LV160A 1Mx16 BotB (2MB)" ,1,size16K, 2,size8K, 1,size32K, 31,size64K }, /* bypass */ 324 | { 0x007F, 0x22C4, size2MB, CMD_TYPE_AMD, "EON EN29LV160A 1Mx16 TopB (2MB)" ,31,size64K, 1,size32K, 2,size8K, 1,size16K }, 325 | { 0x0004, 0x2249, size2MB, CMD_TYPE_AMD, "MBM29LV160B 1Mx16 BotB (2MB)" ,1,size16K, 2,size8K, 1,size32K, 31,size64K }, 326 | { 0x0004, 0x22c4, size2MB, CMD_TYPE_AMD, "MBM29LV160T 1Mx16 TopB (2MB)" ,31,size64K, 1,size32K, 2,size8K, 1,size16K }, 327 | { 0x00C2, 0x2249, size2MB, CMD_TYPE_AMD, "MX29LV160CB 1Mx16 BotB (2MB)" ,1,size16K, 2,size8K, 1,size32K, 31,size64K }, 328 | { 0x00C2, 0x22c4, size2MB, CMD_TYPE_AMD, "MX29LV160CT 1Mx16 TopB (2MB)" ,31,size64K, 1,size32K, 2,size8K, 1,size16K }, 329 | { 0x00EC, 0x2275, size2MB, CMD_TYPE_AMD, "K8D1716UTC 1Mx16 TopB (2MB)" ,31,size64K, 8,size8K, 0,0, 0,0 }, 330 | { 0x00EC, 0x2277, size2MB, CMD_TYPE_AMD, "K8D1716UBC 1Mx16 BotB (2MB)" ,8,size8K, 31,size64K, 0,0, 0,0 }, /* bypass */ 331 | { 0x0020, 0x2249, size2MB, CMD_TYPE_AMD, "ST M29W160EB 1Mx16 BotB (2MB)" ,1,size16K, 2,size8K, 1,size32K, 31,size64K }, 332 | { 0x0020, 0x22c4, size2MB, CMD_TYPE_AMD, "ST M29W160ET 1Mx16 TopB (2MB)" ,31,size64K, 1,size32K, 2,size8K, 1,size16K }, 333 | { 0x00C2, 0x0014, size2MB, CMD_TYPE_SPI, "Macronix MX25L160A (2MB) Serial" ,32,size64K, 0,0, 0,0, 0,0 }, /* new */ 334 | { 0x001f, 0x2600, size2MB, CMD_TYPE_SPI, "Atmel AT45DB161B (2MB) Serial" ,512,sizeA4K, 0,0, 0,0, 0,0 }, /* new */ 335 | { 0x0040, 0x0000, size2MB, CMD_TYPE_SPI, "Atmel AT45DB161B (2MB) Serial" ,512,sizeA4K, 0,0, 0,0, 0,0 }, /* new */ 336 | 337 | { 0x00EC, 0x22A0, size4MB, CMD_TYPE_AMD, "K8D3216UTC 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 338 | { 0x00EC, 0x22A2, size4MB, CMD_TYPE_AMD, "K8D3216UBC 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 339 | 340 | { 0x00C2, 0x2015, size2MB, CMD_TYPE_SPI, "Macronix MX25L1605D (2MB) Serial" ,32,size64K, 0,0, 0,0, 0,0 }, /* new */ 341 | { 0x00C2, 0x2016, size4MB, CMD_TYPE_SPI, "Macronix MX25L3205D (4MB) Serial" ,64,size64K, 0,0, 0,0, 0,0 }, /* new */ 342 | { 0x00C2, 0x2017, size8MB, CMD_TYPE_SPI, "Macronix MX25L6405D (8MB) Serial" ,128,size64K, 0,0, 0,0, 0,0 }, /* new */ 343 | 344 | 345 | { 0x0020, 0x2015, size2MB, CMD_TYPE_SPI, "STMicro M25P16 (2MB) Serial" ,32,size64K, 0,0, 0,0, 0,0 }, /* new */ 346 | { 0x0020, 0x2016, size4MB, CMD_TYPE_SPI, "STMicro M25P32 (4MB) Serial" ,64,size64K, 0,0, 0,0, 0,0 }, /* new */ 347 | { 0x0020, 0x2017, size8MB, CMD_TYPE_SPI, "STMicro M25P64 (8MB) Serial" ,128,size64K, 0,0, 0,0, 0,0 }, /* new */ 348 | { 0x0020, 0x2018, size16MB, CMD_TYPE_SPI, "STMicro M25P128 (16MB) Serial" ,32,size256K, 0,0, 0,0, 0,0 }, /* new */ 349 | 350 | 351 | { 0x0001, 0x2200, size4MB, CMD_TYPE_AMD, "AMD 29lv320MB 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 352 | { 0x0001, 0x227E, size4MB, CMD_TYPE_AMD, "AMD 29lv320MT 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 353 | { 0x0001, 0x2201, size4MB, CMD_TYPE_AMD, "AMD 29lv320MT 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 354 | { 0x0098, 0x009C, size4MB, CMD_TYPE_AMD, "TC58FVB321 2Mx16 BotB (4MB)" ,1,size16K, 2,size8K, 1,size32K, 63,size64K }, 355 | { 0x0098, 0x009A, size4MB, CMD_TYPE_AMD, "TC58FVT321 2Mx16 TopB (4MB)" ,63,size64K, 1,size32K, 2,size8K, 1,size16K }, 356 | { 0x001F, 0x00C0, size4MB, CMD_TYPE_AMD, "AT49BV/LV16X 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 357 | { 0x001F, 0x00C2, size4MB, CMD_TYPE_AMD, "AT49BV/LV16XT 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 358 | { 0x0004, 0x2253, size4MB, CMD_TYPE_AMD, "MBM29DL323BE 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 359 | { 0x0004, 0x2250, size4MB, CMD_TYPE_AMD, "MBM29DL323TE 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 360 | { 0x0001, 0x22f9, size4MB, CMD_TYPE_AMD, "AMD 29lv320DB 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 361 | { 0x0001, 0x22f6, size4MB, CMD_TYPE_AMD, "AMD 29lv320DT 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 362 | { 0x0004, 0x22F9, size4MB, CMD_TYPE_AMD, "MBM29LV320BE 2Mx16 BotB (4MB)" ,1,size16K, 2,size8K, 1,size32K, 63,size64K }, 363 | { 0x0004, 0x22F6, size4MB, CMD_TYPE_AMD, "MBM29LV320TE 2Mx16 TopB (4MB)" ,63,size64K, 1,size32K, 2,size8K, 1,size16K }, 364 | { 0x00C2, 0x22A8, size4MB, CMD_TYPE_AMD, "MX29LV320B 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 365 | { 0x00C2, 0x00A8, size4MB, CMD_TYPE_AMD, "MX29LV320B 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 366 | { 0x00C2, 0x00A7, size4MB, CMD_TYPE_AMD, "MX29LV320T 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 367 | { 0x00C2, 0x22A7, size4MB, CMD_TYPE_AMD, "MX29LV320T 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 368 | { 0x0020, 0x22CB, size4MB, CMD_TYPE_AMD, "ST 29w320DB 2Mx16 BotB (4MB)" ,1,size16K, 2,size8K, 1,size32K, 63,size64K }, 369 | { 0x0020, 0x22CA, size4MB, CMD_TYPE_AMD, "ST 29w320DT 2Mx16 TopB (4MB)" ,63,size64K, 1,size32K, 2,size8K, 1,size16K }, 370 | 371 | { 0x00C2, 0x22C9, size16MB, CMD_TYPE_AMD, "MX29LV640B 4Mx16 TopB (16MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, 372 | { 0x00C2, 0x22CB, size16MB, CMD_TYPE_AMD, "MX29LV640B 4Mx16 BotB (16MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, 373 | 374 | 375 | { 0x00DA, 0x22BA, size4MB, CMD_TYPE_AMD, "W19B(L)320ST 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, /* new */ 376 | { 0x00DA, 0x222A, size4MB, CMD_TYPE_AMD, "W19B(L)320SB 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, /* new */ 377 | { 0x22DA, 0x222A, size4MB, CMD_TYPE_AMD, "W19B(L)320SB 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 378 | 379 | { 0x0020, 0x225C, size4MB, CMD_TYPE_AMD, "M29DW324DT 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, /* new */ 380 | { 0x0020, 0x225D, size4MB, CMD_TYPE_AMD, "M29DW324DB 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, /* new */ 381 | 382 | { 0x0098, 0x0057, size8MB, CMD_TYPE_AMD, "TC58FVM6T2A 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, /* new */ 383 | { 0x0098, 0x0058, size8MB, CMD_TYPE_AMD, "TC58FVM6B2A 4Mx16 BopB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, /* new */ 384 | 385 | { 0x00EC, 0x22E0, size8MB, CMD_TYPE_AMD, "K8D6316UTM 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, /* new */ 386 | { 0x00EC, 0x22E2, size8MB, CMD_TYPE_AMD, "K8D6316UBM 4Mx16 BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, /* new */ 387 | 388 | /* BSC */ 389 | { 0x0089, 0x8891, size2MB, CMD_TYPE_BSC, "Intel 28F160B3 1Mx16 BotB (2MB)" ,8,size8K, 31,size64K, 0,0, 0,0 }, 390 | { 0x0089, 0x8890, size2MB, CMD_TYPE_BSC, "Intel 28F160B3 1Mx16 TopB (2MB)" ,31,size64K, 8,size8K, 0,0, 0,0 }, 391 | { 0x0089, 0x88C3, size2MB, CMD_TYPE_BSC, "Intel 28F160C3 1Mx16 BotB (2MB)" ,8,size8K, 31,size64K, 0,0, 0,0 }, 392 | { 0x0089, 0x88C2, size2MB, CMD_TYPE_BSC, "Intel 28F160C3 1Mx16 TopB (2MB)" ,31,size64K, 8,size8K, 0,0, 0,0 }, 393 | 394 | { 0x0089, 0x8897, size4MB, CMD_TYPE_BSC, "Intel 28F320B3 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 395 | { 0x0089, 0x8896, size4MB, CMD_TYPE_BSC, "Intel 28F320B3 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 396 | { 0x0089, 0x88C5, size4MB, CMD_TYPE_BSC, "Intel 28F320C3 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 397 | { 0x0089, 0x88C4, size4MB, CMD_TYPE_BSC, "Intel 28F320C3 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 398 | { 0x00b0, 0x00e3, size4MB, CMD_TYPE_BSC, "Sharp 28F320BJE 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 399 | 400 | { 0x0089, 0x8899, size8MB, CMD_TYPE_BSC, "Intel 28F640B3 4Mx16 BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, 401 | { 0x0089, 0x8898, size8MB, CMD_TYPE_BSC, "Intel 28F640B3 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, 402 | { 0x0089, 0x88CD, size8MB, CMD_TYPE_BSC, "Intel 28F640C3 4Mx16 BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, 403 | { 0x0089, 0x88CC, size8MB, CMD_TYPE_BSC, "Intel 28F640C3 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, 404 | 405 | /* SCS */ 406 | { 0x00b0, 0x00d0, size2MB, CMD_TYPE_SCS, "Intel 28F160S3/5 1Mx16 (2MB)" ,32,size64K, 0,0, 0,0, 0,0 }, 407 | 408 | { 0x0089, 0x0016, size4MB, CMD_TYPE_SCS, "Intel 28F320J3 2Mx16 (4MB)" ,32,size128K, 0,0, 0,0, 0,0 }, 409 | { 0x0089, 0x0014, size4MB, CMD_TYPE_SCS, "Intel 28F320J5 2Mx16 (4MB)" ,32,size128K, 0,0, 0,0, 0,0 }, 410 | { 0x00b0, 0x00d4, size4MB, CMD_TYPE_SCS, "Intel 28F320S3/5 2Mx16 (4MB)" ,64,size64K, 0,0, 0,0, 0,0 }, 411 | 412 | { 0x0089, 0x0017, size8MB, CMD_TYPE_SCS, "Intel 28F640J3 4Mx16 (8MB)" ,64,size128K, 0,0, 0,0, 0,0 }, 413 | { 0x0089, 0x0015, size8MB, CMD_TYPE_SCS, "Intel 28F640J5 4Mx16 (8MB)" ,64,size128K, 0,0, 0,0, 0,0 }, 414 | 415 | { 0x0089, 0x0018, size16MB, CMD_TYPE_SCS, "Intel 28F128J3 8Mx16 (16MB)" ,128,size128K, 0,0, 0,0, 0,0 }, 416 | 417 | /* SST */ 418 | 419 | { 0x00BF, 0x234B, size2MB, CMD_TYPE_SST, "SST39VF1601 1Mx16 BotB (2MB)" ,8,size8K, 31,size64K, 0,0, 0,0 }, 420 | { 0x00BF, 0x234A, size2MB, CMD_TYPE_SST, "SST39VF1602 1Mx16 TopB (2MB)" ,31,size64K, 8,size8K, 0,0, 0,0 }, 421 | 422 | { 0x00BF, 0x235B, size4MB, CMD_TYPE_SST, "SST39VF3201 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 423 | { 0x00BF, 0x235A, size4MB, CMD_TYPE_SST, "SST39VF3202 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 424 | 425 | { 0x00BF, 0x236B, size8MB, CMD_TYPE_SST, "SST39VF6401 4Mx16 BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, 426 | { 0x00BF, 0x236A, size8MB, CMD_TYPE_SST, "SST39VF6402 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, 427 | { 0x00BF, 0x236D, size8MB, CMD_TYPE_SST, "SST39VF6401B 4Mx16 BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, 428 | { 0x00BF, 0x236C, size8MB, CMD_TYPE_SST, "SST39VF6402B 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, 429 | 430 | // See Spansion hack details for reasoning for the unusual vendid 431 | { 0x017E, 0x1A00, size4MB, CMD_TYPE_AMD, "Spansion S29GL032M BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 432 | { 0x017E, 0x1A01, size4MB, CMD_TYPE_AMD, "Spansion S29GL032M TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 433 | { 0x017E, 0x1000, size8MB, CMD_TYPE_AMD, "Spansion S29GL064M BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, 434 | { 0x017E, 0x1001, size8MB, CMD_TYPE_AMD, "Spansion S29GL064M TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, 435 | 436 | // patch from OpenWRT jal2 for ti-ar7 ip8100 437 | { 0x017E, 0x1301, size8MB, CMD_TYPE_AMD, "Spansion S29GL064M U (8MB)" ,128,size64K, 0,0, 0,0, 0,0 }, 438 | 439 | { 0x017E, 0x2101, size16MB, CMD_TYPE_AMD, "Spansion S29GL128P U (16MB)" ,128,size128K, 0,0, 0,0, 0,0 }, 440 | { 0x017E, 0x1200, size16MB, CMD_TYPE_AMD, "Spansion S29GL128M U (16MB)" ,128,size128K, 0,0, 0,0, 0,0 }, 441 | { 0x017E, 0x2201, size32MB, CMD_TYPE_AMD, "Spansion S29GL256P U (32MB)" ,256,size128K, 0,0, 0,0, 0,0 }, 442 | { 0x017E, 0x2301, size64MB, CMD_TYPE_AMD, "Spansion S29GL512P U (64MB)" ,512,size128K, 0,0, 0,0, 0,0 }, 443 | { 0x017E, 0x2801, size128MB, CMD_TYPE_AMD, "Spansion S29GL01GP U (128MB)" ,1024,size128K, 0,0, 0,0, 0,0 }, 444 | 445 | { 0x0001, 0x0214, size2MB, CMD_TYPE_SPI, "Spansion S25FL016A (2MB) Serial" ,32,size64K, 0,0, 0,0, 0,0 }, /* new */ 446 | { 0x0001, 0x0215, size4MB, CMD_TYPE_SPI, "Spansion S25FL032A (4MB) Serial" ,64,size64K, 0,0, 0,0, 0,0 }, /* new */ 447 | { 0x0001, 0x0216, size8MB, CMD_TYPE_SPI, "Spansion S25FL064A (8MB) Serial" ,128,size64K, 0,0, 0,0, 0,0 }, /* new */ 448 | 449 | 450 | // Winbond 3-stage ID chips 451 | { 0xDA7E, 0x0A00, size4MB, CMD_TYPE_AMD, "Winbond W19B320AB BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 452 | { 0xDA7E, 0x0A01, size4MB, CMD_TYPE_AMD, "Winbond W19B320AT TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 453 | { 0x00EF, 0x3016, size4MB, CMD_TYPE_SPI, "Winbond W25X32 (4MB) Serial" ,64,size64K, 0,0, 0,0, 0,0 }, /* new */ 454 | { 0x00EF, 0x3017, size8MB, CMD_TYPE_SPI, "Winbond W25X64 (8MB) Serial" ,128,size64K, 0,0, 0,0, 0,0 }, /* new */ 455 | // EON 456 | { 0x007f, 0x22F9, size4MB, CMD_TYPE_AMD, "EON EN29LV320 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, /* wrt54gl v1.1 */ 457 | { 0x007f, 0x22F6, size4MB, CMD_TYPE_AMD, "EON EN29LV320 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, /* bypass */ 458 | { 0x007F, 0x22C9, size8MB, CMD_TYPE_AMD, "EON EN29LV640 4Mx16 TopB (8MB)" ,127,size64K, 8,size8K, 0,0, 0,0 }, /* bypass */ 459 | { 0x007F, 0x22Cb, size8MB, CMD_TYPE_AMD, "EON EN29LV640 4Mx16 BotB (8MB)" ,8,size8K, 127,size64K, 0,0, 0,0 }, /* bypass */ 460 | // Atmel 461 | { 0x001F, 0x00C8, size4MB, CMD_TYPE_AMD, "AT49BV322A 2Mx16 BotB (4MB)" ,8,size8K, 63,size64K, 0,0, 0,0 }, 462 | { 0x001F, 0x00C9, size4MB, CMD_TYPE_AMD, "AT49BV322A(T) 2Mx16 TopB (4MB)" ,63,size64K, 8,size8K, 0,0, 0,0 }, 463 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 464 | }; 465 | 466 | 467 | // ----------------------------------------- 468 | // ---- Start of Compiler Specific Code ---- 469 | // ----------------------------------------- 470 | 471 | void lpt_openport(void) 472 | { 473 | #ifdef WINDOWS_VERSION // ---- Compiler Specific Code ---- 474 | 475 | HANDLE h; 476 | 477 | h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 478 | if (h == INVALID_HANDLE_VALUE) 479 | { 480 | printf("Couldn't access giveio device\n"); 481 | CloseHandle(h); 482 | exit(0); 483 | } 484 | CloseHandle(h); 485 | 486 | #else // ---- Compiler Specific Code ---- 487 | 488 | #ifdef RASPPI // ---- Compiler Specific Code ---- 489 | 490 | int mem_fd; 491 | char *gpio_mem, *gpio_map; 492 | 493 | /* open /dev/mem */ 494 | if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 495 | printf("can't open /dev/mem \n"); 496 | exit(-1); 497 | } 498 | 499 | // Allocate MAP block 500 | if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE - 1))) == NULL) { 501 | printf("allocation error\n"); 502 | exit(-1); 503 | } 504 | 505 | // Make sure pointer is on 4K boundary 506 | if ((unsigned long) gpio_mem % PAGE_SIZE) 507 | gpio_mem += PAGE_SIZE - ((unsigned long) gpio_mem % PAGE_SIZE); 508 | 509 | /* mmap GPIO */ 510 | gpio_map = mmap( 511 | (caddr_t) gpio_mem, 512 | BLOCK_SIZE, 513 | PROT_READ|PROT_WRITE, 514 | MAP_SHARED|MAP_FIXED, 515 | mem_fd, 516 | GPIO_BASE 517 | ); 518 | 519 | if ((long) gpio_map < 0) { 520 | printf("mmap error %ld\n", (long) gpio_map); 521 | exit(-1); 522 | } 523 | 524 | close(mem_fd); 525 | 526 | 527 | // Always use volatile pointer! 528 | gpio = (volatile unsigned *) gpio_map; 529 | 530 | // Set TDO as input and TMS,TCK and TDI as output 531 | 532 | INP_GPIO(TDO); 533 | INP_GPIO(TMS); 534 | INP_GPIO(TCK); 535 | INP_GPIO(TDI); 536 | 537 | OUT_GPIO(TMS); 538 | OUT_GPIO(TCK); 539 | OUT_GPIO(TDI); 540 | 541 | #else 542 | 543 | #ifdef __FreeBSD__ // ---- Compiler Specific Code ---- 544 | 545 | pfd = open("/dev/ppi0", O_RDWR); 546 | if (pfd < 0) 547 | { 548 | perror("Failed to open /dev/ppi0"); 549 | exit(0); 550 | } 551 | if ((ioctl(pfd, PPEXCL) < 0) || (ioctl(pfd, PPCLAIM) < 0)) 552 | { 553 | perror("Failed to lock /dev/ppi0"); 554 | close(pfd); 555 | exit(0); 556 | } 557 | 558 | #else // ---- Compiler Specific Code ---- 559 | 560 | pfd = open("/dev/parport0", O_RDWR); 561 | if (pfd < 0) 562 | { 563 | perror("Failed to open /dev/parport0"); 564 | exit(0); 565 | } 566 | if ((ioctl(pfd, PPEXCL) < 0) || (ioctl(pfd, PPCLAIM) < 0)) 567 | { 568 | perror("Failed to lock /dev/parport0"); 569 | close(pfd); 570 | exit(0); 571 | } 572 | 573 | #endif 574 | 575 | #endif 576 | 577 | #endif 578 | } 579 | 580 | 581 | void lpt_closeport(void) 582 | { 583 | #ifndef WINDOWS_VERSION // ---- Compiler Specific Code ---- 584 | 585 | #ifdef RASPPI 586 | 587 | #else 588 | 589 | #ifndef __FreeBSD__ // ---- Compiler Specific Code ---- 590 | 591 | if (ioctl(pfd, PPRELEASE) < 0) 592 | { 593 | perror("Failed to release /dev/parport0"); 594 | close(pfd); 595 | exit(0); 596 | } 597 | 598 | #endif 599 | 600 | close(pfd); 601 | 602 | #endif 603 | 604 | #endif 605 | } 606 | 607 | // Yoon's extensions for exiting debug mode 608 | 609 | static void return_from_debug_mode(void) 610 | { 611 | ExecuteDebugModule(pracc_return_from_debug); 612 | } 613 | 614 | 615 | static unsigned char clockin(int tms, int tdi) 616 | { 617 | 618 | #ifdef RASPPI 619 | unsigned int data; 620 | #else 621 | unsigned char data; 622 | #endif 623 | 624 | tms = tms ? 1 : 0; 625 | tdi = tdi ? 1 : 0; 626 | 627 | #ifdef RASPPI 628 | 629 | data = (tms << TMS) | (tdi << TDI); 630 | GPIO_CLR = (1 << TCK) | (1 << TMS) | (1 << TDI); 631 | GPIO_SET = data; 632 | cable_wait(); 633 | GPIO_SET = 1 << TCK; 634 | cable_wait(); 635 | 636 | data = GPIO_GET; 637 | data = (data >> TDO) & 1; 638 | 639 | #else 640 | 641 | // yoon's remark we set wtrst_n to be d4 so we are going to drive it low 642 | if (wiggler) data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI)| (1 << WTRST_N); 643 | else data = (1 << TDO) | (0 << TCK) | (tms << TMS) | (tdi << TDI); 644 | cable_wait(); 645 | 646 | 647 | #ifdef WINDOWS_VERSION // ---- Compiler Specific Code ---- 648 | _outp(0x378, data); 649 | #else 650 | 651 | ioctl(pfd, PPWDATA, &data); 652 | #endif 653 | if (wiggler) data = (1 << WTDO) | (1 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 << WTRST_N); 654 | else data = (1 << TDO) | (1 << TCK) | (tms << TMS) | (tdi << TDI); 655 | cable_wait(); 656 | 657 | 658 | #ifdef WINDOWS_VERSION // ---- Compiler Specific Code ---- 659 | _outp(0x378, data); 660 | #else 661 | ioctl(pfd, PPWDATA, &data); 662 | #endif 663 | 664 | #ifdef WINDOWS_VERSION // ---- Compiler Specific Code ---- 665 | data = (unsigned char)_inp(0x379); 666 | #else 667 | ioctl(pfd, PPRSTATUS, &data); 668 | #endif 669 | 670 | data ^= 0x80; 671 | data >>= wiggler?WTDO:TDO; 672 | data &= 1; 673 | 674 | #endif 675 | 676 | return data; 677 | } 678 | 679 | // --------------------------------------- 680 | // ---- End of Compiler Specific Code ---- 681 | // --------------------------------------- 682 | 683 | void test_reset(void) 684 | { 685 | clockin(1, 0); // Run through a handful of clock cycles with TMS high to make sure 686 | clockin(1, 0); // we are in the TEST-LOGIC-RESET state. 687 | clockin(1, 0); 688 | clockin(1, 0); 689 | clockin(1, 0); 690 | clockin(0, 0); // enter runtest-idle 691 | } 692 | 693 | static int curinstr = 0xFFFFFFFF; 694 | void set_instr(int instr) 695 | { 696 | int i; 697 | 698 | if (instr == curinstr) 699 | return; 700 | 701 | clockin(1, 0); // enter select-dr-scan 702 | clockin(1, 0); // enter select-ir-scan 703 | clockin(0, 0); // enter capture-ir 704 | clockin(0, 0); // enter shift-ir (dummy) 705 | for (i=0; i < instruction_length; i++) 706 | { 707 | clockin(i==(instruction_length - 1), (instr>>i)&1); 708 | } 709 | clockin(1, 0); // enter update-ir 710 | clockin(0, 0); // enter runtest-idle 711 | 712 | curinstr = instr; 713 | } 714 | 715 | 716 | static unsigned int ReadWriteData(unsigned int in_data) 717 | { 718 | int i; 719 | unsigned int out_data = 0; 720 | unsigned char out_bit; 721 | 722 | if (DEBUG) printf("INSTR: 0x%04x ", curinstr); 723 | if (DEBUG) printf("W: 0x%08x ", in_data); 724 | 725 | clockin(1, 0); // enter select-dr-scan 726 | clockin(0, 0); // enter capture-dr 727 | clockin(0, 0); // enter shift-dr 728 | for (i = 0 ; i < 32 ; i++) 729 | { 730 | out_bit = clockin((i == 31), ((in_data >> i) & 1)); 731 | out_data = out_data | (out_bit << i); 732 | } 733 | clockin(1,0); // enter update-dr 734 | clockin(0,0); // enter runtest-idle 735 | 736 | if (DEBUG) printf("R: 0x%08x\n", out_data); 737 | 738 | return out_data; 739 | } 740 | 741 | 742 | static unsigned int ReadData(void) 743 | { 744 | return ReadWriteData(0x00); 745 | } 746 | 747 | 748 | void WriteData(unsigned int in_data) 749 | { 750 | ReadWriteData(in_data); 751 | } 752 | 753 | void ShowData(unsigned int value) 754 | { 755 | unsigned int i; 756 | for (i=0; i<32; i++) 757 | printf("%d", (value >> (31-i)) & 1); 758 | printf(" (%08X)\n", value); 759 | } 760 | 761 | unsigned int swap_bytes(unsigned int data, int num_bytes) 762 | { 763 | unsigned int datab[4], i; 764 | 765 | for (i = 0; i < num_bytes; i++) 766 | { 767 | datab[i] = (data >>((num_bytes - i - 1) * 8) & 0xFF); 768 | } 769 | 770 | data = 0x0; 771 | for (i = 0; i < num_bytes; i++) 772 | { 773 | data = (data | (datab[i] <<(8 * i))); 774 | } 775 | return data; 776 | } 777 | 778 | unsigned short byteSwap(unsigned short data) 779 | { 780 | //convert from little to big endian 781 | unsigned short tmp; 782 | tmp=(data<<8)|(data>>8); 783 | return tmp; 784 | } 785 | 786 | 787 | static unsigned int ejtag_read(unsigned int addr) 788 | { 789 | if (USE_DMA) return(ejtag_dma_read(addr)); 790 | else return(ejtag_pracc_read(addr)); 791 | } 792 | 793 | static unsigned int ejtag_read_h(unsigned int addr) 794 | { 795 | if (USE_DMA) return(ejtag_dma_read_h(addr)); 796 | else return(ejtag_pracc_read_h(addr)); 797 | } 798 | 799 | void ejtag_write(unsigned int addr, unsigned int data) 800 | { 801 | if (USE_DMA) ejtag_dma_write(addr, data); 802 | else ejtag_pracc_write(addr, data); 803 | } 804 | 805 | void ejtag_write_h(unsigned int addr, unsigned int data) 806 | { 807 | if (USE_DMA) ejtag_dma_write_h(addr, data); 808 | else ejtag_pracc_write_h(addr, data); 809 | } 810 | 811 | static unsigned int ejtag_dma_read(unsigned int addr) 812 | { 813 | unsigned int data; 814 | int retries = RETRY_ATTEMPTS; 815 | 816 | begin_ejtag_dma_read: 817 | 818 | // Setup Address 819 | set_instr(INSTR_ADDRESS); 820 | WriteData(addr); 821 | 822 | // Initiate DMA Read & set DSTRT 823 | set_instr(INSTR_CONTROL); 824 | ctrl_reg = ReadWriteData(DMAACC | DRWN | DMA_WORD | DSTRT | PROBEN | PRACC); 825 | 826 | // Wait for DSTRT to Clear - Problem Gv8 tornado 827 | if (!((proc_id & 0xfffffff) == 0x535417f)) 828 | { 829 | while (ReadWriteData(DMAACC | PROBEN | PRACC) & DSTRT); 830 | } 831 | 832 | // Read Data 833 | set_instr(INSTR_DATA); 834 | data = ReadData(); 835 | 836 | 837 | // Clear DMA & Check DERR 838 | set_instr(INSTR_CONTROL); 839 | if (ReadWriteData(PROBEN | PRACC) & DERR) 840 | { 841 | if (retries--) goto begin_ejtag_dma_read; 842 | else printf("DMA Read Addr = %08x Data = (%08x)ERROR ON READ\n", addr, data); 843 | } 844 | 845 | return(data); 846 | 847 | 848 | } 849 | 850 | static unsigned int ejtag_dma_read_h(unsigned int addr) 851 | { 852 | unsigned int data; 853 | int retries = RETRY_ATTEMPTS; 854 | 855 | begin_ejtag_dma_read_h: 856 | 857 | // Setup Address 858 | set_instr(INSTR_ADDRESS); 859 | WriteData(addr); 860 | 861 | // Initiate DMA Read & set DSTRT 862 | set_instr(INSTR_CONTROL); 863 | ctrl_reg = ReadWriteData(DMAACC | DRWN | DMA_HALFWORD | DSTRT | PROBEN | PRACC); 864 | 865 | // Wait for DSTRT to Clear 866 | while (ReadWriteData(DMAACC | PROBEN | PRACC) & DSTRT); 867 | 868 | // Read Data 869 | set_instr(INSTR_DATA); 870 | data = ReadData(); 871 | 872 | // Clear DMA & Check DERR 873 | set_instr(INSTR_CONTROL); 874 | if (ReadWriteData(PROBEN | PRACC) & DERR) 875 | { 876 | if (retries--) goto begin_ejtag_dma_read_h; 877 | else printf("DMA Read Addr = %08x Data = (%08x)ERROR ON READ\n", addr, data); 878 | } 879 | // Handle the bigendian / littleendian 880 | 881 | if ( addr & 0x2 ) 882 | data = (data>>16)&0xffff; 883 | else 884 | data = (data&0x0000ffff); 885 | 886 | return(data); 887 | 888 | } 889 | 890 | void ejtag_dma_write(unsigned int addr, unsigned int data) 891 | { 892 | int retries = RETRY_ATTEMPTS; 893 | 894 | begin_ejtag_dma_write: 895 | 896 | // Setup Address 897 | set_instr(INSTR_ADDRESS); 898 | WriteData(addr); 899 | 900 | // Setup Data 901 | set_instr(INSTR_DATA); 902 | WriteData(data); 903 | 904 | // Initiate DMA Write & set DSTRT 905 | set_instr(INSTR_CONTROL); 906 | ctrl_reg = ReadWriteData(DMAACC | DMA_WORD | DSTRT | PROBEN | PRACC); 907 | 908 | // Wait for DSTRT to Clear 909 | while (ReadWriteData(DMAACC | PROBEN | PRACC) & DSTRT); 910 | 911 | // Clear DMA & Check DERR 912 | set_instr(INSTR_CONTROL); 913 | if (ReadWriteData(PROBEN | PRACC) & DERR) 914 | { 915 | if (retries--) goto begin_ejtag_dma_write; 916 | else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr); 917 | } 918 | } 919 | 920 | 921 | void ejtag_dma_write_h(unsigned int addr, unsigned int data) 922 | { 923 | int retries = RETRY_ATTEMPTS; 924 | 925 | begin_ejtag_dma_write_h: 926 | 927 | // Setup Address 928 | set_instr(INSTR_ADDRESS); 929 | WriteData(addr); 930 | 931 | // Setup Data 932 | set_instr(INSTR_DATA); 933 | WriteData(data); 934 | 935 | // Initiate DMA Write & set DSTRT 936 | set_instr(INSTR_CONTROL); 937 | ctrl_reg = ReadWriteData(DMAACC | DMA_HALFWORD | DSTRT | PROBEN | PRACC); 938 | 939 | // Wait for DSTRT to Clear 940 | while (ReadWriteData(DMAACC | PROBEN | PRACC) & DSTRT); 941 | 942 | // Clear DMA & Check DERR 943 | set_instr(INSTR_CONTROL); 944 | if (ReadWriteData(PROBEN | PRACC) & DERR) 945 | { 946 | if (retries--) goto begin_ejtag_dma_write_h; 947 | else printf("DMA Write Addr = %08x Data = ERROR ON WRITE\n", addr); 948 | } 949 | } 950 | 951 | static unsigned int ejtag_pracc_read(unsigned int addr) 952 | { 953 | address_register = addr | 0xA0000000; // Force to use uncached segment 954 | data_register = 0x0; 955 | ExecuteDebugModule(pracc_readword_code_module); 956 | return(data_register); 957 | } 958 | 959 | void ejtag_pracc_write(unsigned int addr, unsigned int data) 960 | { 961 | address_register = addr | 0xA0000000; // Force to use uncached segment 962 | data_register = data; 963 | ExecuteDebugModule(pracc_writeword_code_module); 964 | } 965 | 966 | static unsigned int ejtag_pracc_read_h(unsigned int addr) 967 | { 968 | address_register = addr | 0xA0000000; // Force to use uncached segment 969 | data_register = 0x0; 970 | ExecuteDebugModule(pracc_readhalf_code_module); 971 | return(data_register); 972 | } 973 | 974 | 975 | void ejtag_pracc_write_h(unsigned int addr, unsigned int data) 976 | { 977 | address_register = addr | 0xA0000000; // Force to use uncached segment 978 | data_register = data; 979 | ExecuteDebugModule(pracc_writehalf_code_module); 980 | } 981 | 982 | void setup_memory_4712(void) 983 | { 984 | printf("Configuring SDRAM... "); 985 | 986 | ejtag_dma_write(0x18006f98,0x00030001); // #define SBTMSTATELOW offset 0xf00 + 0x98 987 | ejtag_dma_write(0x18006f98,0x00030000); 988 | ejtag_dma_write(0x18006f98,0x00010000); 989 | ejtag_dma_write(0x18006004,0x00048000); // #define MEMC_SD_CONFIG_INIT 0x00048000 990 | ejtag_dma_write(0x1800601c,0x000754da); // #define MEMC_SD_DRAMTIM3_INIT 0x000754da sbmemc.h 991 | ejtag_dma_write(0x18006034,0x23232323); 992 | ejtag_dma_write(0x18006038,0x14500200); // #define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 For corerev 1 (4712) 993 | ejtag_dma_write(0x1800603c,0x22021416); // #define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 For corerev 1 (4712) 994 | ejtag_dma_write(0x18006000,0x00000002); // #define MEMC_SD_CONTROL_INIT0 0x00000002 995 | ejtag_dma_write(0x18006000,0x00000008); // #define MEMC_SD_CONTROL_INIT1 0x00000008 996 | ejtag_dma_write(0x18006000,0x00000004); 997 | ejtag_dma_write(0x18006000,0x00000004); 998 | ejtag_dma_write(0x18006000,0x00000004); 999 | ejtag_dma_write(0x18006000,0x00000004); 1000 | ejtag_dma_write(0x18006000,0x00000004); 1001 | ejtag_dma_write(0x18006000,0x00000004); 1002 | ejtag_dma_write(0x18006000,0x00000004); 1003 | ejtag_dma_write(0x18006000,0x00000004); 1004 | ejtag_dma_write(0x18006008,0x0000840f); // #define MEMC_SD_REFRESH_INIT 0x0000840f 1005 | ejtag_dma_write(0x18006010,0x00000032); // sdram_config=0x0032 1006 | ejtag_dma_write(0x18006000,0x00000010); // #define MEMC_CONTROL_INIT2 0x00000010 1007 | ejtag_dma_write(0x18006000,0x00000001); // 1008 | 1009 | 1010 | printf("Done\n\n"); 1011 | } 1012 | 1013 | void setup_memory_5352(void) 1014 | { 1015 | printf("Configuring SDRAM... "); 1016 | 1017 | ejtag_dma_write(0x18004f98,0x00030001); // SBTMSTATELOW offset 0xf00 + 0x98 1018 | ejtag_dma_write(0x18004f98,0x00030000); 1019 | ejtag_dma_write(0x18004f98,0x00010000); 1020 | ejtag_dma_write(0x18004004,0x0004810b); // MEMC_SD_CONFIG_INIT 0x00048000 1021 | ejtag_dma_write(0x1800401c,0x000754d9); // MEMC_SD_DRAMTIM3_INIT 0x000754d9 sbmemc.h 1022 | ejtag_dma_write(0x18004034,0x23232323); 1023 | ejtag_dma_write(0x18004038,0x14500200); // MEMC_SD1_WRNCDLCOR_INIT 0x14500200 For corerev 1 (4712) 1024 | ejtag_dma_write(0x1800403c,0x21021400); // MEMC_SD1_MISCDLYCTL_INIT 0x00021416 For corerev 1 (4712) 1025 | ejtag_dma_write(0x18004000,0x00000002); // MEMC_SD_CONTROL_INIT0 0x00000002 1026 | ejtag_dma_write(0x18004000,0x00000008); // MEMC_SD_CONTROL_INIT1 0x00000008 1027 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1028 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1029 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1030 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1031 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1032 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1033 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1034 | ejtag_dma_write(0x18004000,0x00000004); // MEMC_SD_CONTROL_INIT2 1035 | ejtag_dma_write(0x18004008,0x0000840f); // MEMC_SD_REFRESH_INIT 0x0000840f 1036 | ejtag_dma_write(0x18004010,0x00000062); // sdram_config=0x0062 1037 | ejtag_dma_write(0x18004000,0x00000010); // MEMC_SD_CONTROL_INIT3 1038 | ejtag_dma_write(0x18004000,0x00000001); // MEMC_SD_CONTROL_INIT4 1039 | 1040 | printf("Done\n\n"); 1041 | } 1042 | 1043 | void readmem_4712(void) 1044 | { 1045 | int temp; 1046 | 1047 | printf("Printing SDRAM\n"); 1048 | 1049 | temp = ejtag_read(0x18006f98); 1050 | printf("SDRAM = 0x%08x\n", temp); 1051 | temp = ejtag_read(0x18006f98); 1052 | printf("SDRAM = 0x%08x\n", temp); 1053 | temp = ejtag_read(0x18006f98);; 1054 | printf("SDRAM = 0x%08x\n", temp); 1055 | temp = ejtag_read(0x18006004); 1056 | printf("SDRAM = 0x%08x\n", temp); 1057 | temp = ejtag_read(0x1800601c); 1058 | printf("SDRAM = 0x%08x\n", temp); 1059 | temp = ejtag_read(0x18006034); 1060 | printf("SDRAM = 0x%08x\n", temp); 1061 | temp = ejtag_read(0x18006038); 1062 | printf("SDRAM = 0x%08x\n", temp); 1063 | temp = ejtag_read(0x1800603c); 1064 | printf("SDRAM = 0x%08x\n", temp); 1065 | temp = ejtag_read(0x18006000); 1066 | printf("SDRAM = 0x%08x\n", temp); 1067 | temp = ejtag_read(0x18006000); 1068 | printf("SDRAM = 0x%08x\n", temp); 1069 | temp = ejtag_read(0x18006000); 1070 | printf("SDRAM = 0x%08x\n", temp); 1071 | temp = ejtag_read(0x18006000); 1072 | printf("SDRAM = 0x%08x\n", temp); 1073 | temp = ejtag_read(0x18006000); 1074 | printf("SDRAM = 0x%08x\n", temp); 1075 | temp = ejtag_read(0x18006000); 1076 | printf("SDRAM = 0x%08x\n", temp); 1077 | temp = ejtag_read(0x18006000); 1078 | printf("SDRAM = 0x%08x\n", temp); 1079 | temp = ejtag_read(0x18006000); 1080 | printf("SDRAM = 0x%08x\n", temp); 1081 | temp = ejtag_read(0x18006000); 1082 | printf("SDRAM = 0x%08x\n", temp); 1083 | temp = ejtag_read(0x18006000); 1084 | printf("SDRAM = 0x%08x\n", temp); 1085 | temp = ejtag_read(0x18006008); 1086 | printf("SDRAM = 0x%08x\n", temp); 1087 | temp = ejtag_read(0x18006010); 1088 | printf("SDRAM = 0x%08x\n", temp); 1089 | temp = ejtag_read(0x18006000); 1090 | printf("SDRAM = 0x%08x\n", temp); 1091 | temp = ejtag_read(0x18006000); 1092 | printf("SDRAM = 0x%08x\n", temp); 1093 | 1094 | } 1095 | 1096 | void readmem_5352(void) 1097 | { 1098 | int temp = 0; 1099 | 1100 | printf("Printing SDRAM\n"); 1101 | 1102 | temp = ejtag_read(0x18004f98); 1103 | printf("SDRAM = 0x%08x\n", temp); 1104 | temp = ejtag_read(0x18004f98); 1105 | printf("SDRAM = 0x%08x\n", temp); 1106 | temp = ejtag_read(0x18004f98);; 1107 | printf("SDRAM = 0x%08x\n", temp); 1108 | temp = ejtag_read(0x18004004); 1109 | printf("SDRAM = 0x%08x\n", temp); 1110 | temp = ejtag_read(0x1800401c); 1111 | printf("SDRAM = 0x%08x\n", temp); 1112 | temp = ejtag_read(0x18004034); 1113 | printf("SDRAM = 0x%08x\n", temp); 1114 | temp = ejtag_read(0x18004038); 1115 | printf("SDRAM = 0x%08x\n", temp); 1116 | temp = ejtag_read(0x1800403c); 1117 | printf("SDRAM = 0x%08x\n", temp); 1118 | temp = ejtag_read(0x18004000); 1119 | printf("SDRAM = 0x%08x\n", temp); 1120 | temp = ejtag_read(0x18004000); 1121 | printf("SDRAM = 0x%08x\n", temp); 1122 | temp = ejtag_read(0x18004000); 1123 | printf("SDRAM = 0x%08x\n", temp); 1124 | temp = ejtag_read(0x18004000); 1125 | printf("SDRAM = 0x%08x\n", temp); 1126 | temp = ejtag_read(0x18004000); 1127 | printf("SDRAM = 0x%08x\n", temp); 1128 | temp = ejtag_read(0x18004000); 1129 | printf("SDRAM = 0x%08x\n", temp); 1130 | temp = ejtag_read(0x18004000); 1131 | printf("SDRAM = 0x%08x\n", temp); 1132 | temp = ejtag_read(0x18004000); 1133 | printf("SDRAM = 0x%08x\n", temp); 1134 | temp = ejtag_read(0x18004000); 1135 | printf("SDRAM = 0x%08x\n", temp); 1136 | temp = ejtag_read(0x18004000); 1137 | printf("SDRAM = 0x%08x\n", temp); 1138 | temp = ejtag_read(0x18004008); 1139 | printf("SDRAM = 0x%08x\n", temp); 1140 | temp = ejtag_read(0x18004010); 1141 | printf("SDRAM = 0x%08x\n", temp); 1142 | temp = ejtag_read(0x18004000); 1143 | printf("SDRAM = 0x%08x\n", temp); 1144 | temp = ejtag_read(0x18004000); 1145 | printf("SDRAM = 0x%08x\n", temp); 1146 | 1147 | } 1148 | 1149 | 1150 | void ExecuteDebugModule(unsigned int *pmodule) 1151 | { 1152 | unsigned int ctrl_reg; 1153 | unsigned int address; 1154 | unsigned int data = 0; 1155 | unsigned int offset = 0; 1156 | int finished = 0; 1157 | int DEBUGMSG = 0; 1158 | 1159 | if (DEBUGMSG) printf("DEBUGMODULE: Start module.\n"); 1160 | 1161 | // Feed the chip an array of 32 bit values into the processor via the EJTAG port as instructions. 1162 | while (1) 1163 | { 1164 | // Read the control register. Make sure an access is requested, then do it. 1165 | while (1) 1166 | { 1167 | set_instr(INSTR_CONTROL); 1168 | ctrl_reg = ReadWriteData(PRACC | PROBEN | SETDEV); 1169 | if (ctrl_reg & PRACC) 1170 | break; 1171 | if (DEBUGMSG) printf("DEBUGMODULE: No memory access in progress!\n"); 1172 | } 1173 | 1174 | set_instr(INSTR_ADDRESS); 1175 | address = ReadData(); 1176 | 1177 | // Check for read or write 1178 | if (ctrl_reg & PRNW) // Bit set for a WRITE 1179 | { 1180 | // Read the data out 1181 | set_instr(INSTR_DATA); 1182 | data = ReadData(); 1183 | 1184 | // Clear the access pending bit (let the processor eat!) 1185 | set_instr(INSTR_CONTROL); 1186 | ctrl_reg = ReadWriteData(PROBEN | SETDEV); 1187 | 1188 | // Processor is writing to us 1189 | if (DEBUGMSG) printf("DEBUGMODULE: Write 0x%08X to address 0x%08X\n", data, address); 1190 | // Handle Debug Write 1191 | // If processor is writing to one of our psuedo virtual registers then save off data 1192 | if (address == MIPS_VIRTUAL_ADDRESS_ACCESS) address_register = data; 1193 | if (address == MIPS_VIRTUAL_DATA_ACCESS) data_register = data; 1194 | } 1195 | 1196 | else 1197 | 1198 | { 1199 | // Check to see if its reading at the debug vector. The first pass through 1200 | // the module is always read at the vector, so the first one we allow. When 1201 | // the second read from the vector occurs we are done and just exit. 1202 | if (address == MIPS_DEBUG_VECTOR_ADDRESS) 1203 | { 1204 | if (finished++) // Allows ONE pass 1205 | { 1206 | if (DEBUGMSG) printf("DEBUGMODULE: Finished module.\n"); 1207 | return; 1208 | } 1209 | } 1210 | 1211 | // Processor is reading from us 1212 | if (address >= MIPS_DEBUG_VECTOR_ADDRESS) 1213 | { 1214 | // Reading an instruction from our module so fetch the instruction from the module 1215 | offset = (address - MIPS_DEBUG_VECTOR_ADDRESS) / 4; 1216 | data = *(unsigned int *)(pmodule + offset); 1217 | if (DEBUGMSG) printf("DEBUGMODULE: Instruction read at 0x%08X offset -> %04d data -> 0x%08X\n", address, offset, data); //fflush(stdout); 1218 | } 1219 | else 1220 | { 1221 | // Reading from our virtual register area 1222 | if (DEBUGMSG) printf("DEBUGMODULE: Read address 0x%08X data = 0x%08X\n", address, data); 1223 | // Handle Debug Read 1224 | // If processor is reading from one of our psuedo virtual registers then give it data 1225 | if (address == MIPS_VIRTUAL_ADDRESS_ACCESS) data = address_register; 1226 | if (address == MIPS_VIRTUAL_DATA_ACCESS) data = data_register; 1227 | } 1228 | 1229 | // Send the data out 1230 | set_instr(INSTR_DATA); 1231 | data = ReadWriteData(data); 1232 | 1233 | // Clear the access pending bit (let the processor eat!) 1234 | set_instr(INSTR_CONTROL); 1235 | ctrl_reg = ReadWriteData(PROBEN | SETDEV); 1236 | 1237 | } 1238 | } 1239 | } 1240 | 1241 | void chip_detect(void) 1242 | { 1243 | unsigned int id = 0x0; 1244 | 1245 | processor_chip_type* processor_chip = processor_chip_list; 1246 | 1247 | lpt_openport(); 1248 | 1249 | printf("Probing bus ... "); 1250 | 1251 | if (skipdetect) 1252 | { 1253 | // Manual Override CPU Chip ID 1254 | test_reset(); 1255 | instruction_length = instrlen; 1256 | set_instr(INSTR_IDCODE); 1257 | id = ReadData(); 1258 | printf("Done\n\n"); 1259 | printf("Instruction Length set to %d\n\n",instruction_length); 1260 | printf("CPU Chip ID: "); 1261 | ShowData(id); 1262 | printf("*** CHIP DETECTION OVERRIDDEN ***\n\n"); 1263 | return; 1264 | } 1265 | else 1266 | { 1267 | // Auto Detect CPU Chip ID 1268 | while (processor_chip->chip_id) 1269 | { 1270 | test_reset(); 1271 | if (instrlen) 1272 | instruction_length = instrlen; 1273 | else 1274 | instruction_length = processor_chip->instr_length; 1275 | set_instr(INSTR_IDCODE); 1276 | id = ReadData(); 1277 | if (id == processor_chip->chip_id) 1278 | { 1279 | printf("Done\n\n"); 1280 | printf("Instruction Length set to %d\n\n",instruction_length); 1281 | printf("CPU Chip ID: "); 1282 | ShowData(id); 1283 | printf("*** Found a %s chip ***\n\n", processor_chip->chip_descr); 1284 | proc_id = id; 1285 | 1286 | return; 1287 | } 1288 | processor_chip++; 1289 | } 1290 | } 1291 | 1292 | printf("Done\n\n"); 1293 | printf("Instruction Length set to %d\n\n",instruction_length); 1294 | printf("CPU Chip ID: "); 1295 | ShowData(id); 1296 | printf("*** Unknown or NO CPU Chip ID Detected ***\n\n"); 1297 | 1298 | printf("*** Possible Causes:\n"); 1299 | printf(" 1) Device is not Connected.\n"); 1300 | printf(" 2) Device is not Powered On.\n"); 1301 | printf(" 3) Improper JTAG Cable.\n"); 1302 | printf(" 4) Unrecognized CPU Chip ID.\n"); 1303 | 1304 | chip_shutdown();; 1305 | exit(0); 1306 | } 1307 | 1308 | void check_ejtag_features() 1309 | { 1310 | unsigned int features; 1311 | 1312 | set_instr(INSTR_IMPCODE); 1313 | features = ReadData(); 1314 | 1315 | printf(" - EJTAG IMPCODE ....... : "); 1316 | ShowData(features); 1317 | 1318 | // EJTAG Version 1319 | ejtag_version = (features >> 29) & 7; 1320 | printf(" - EJTAG Version ....... : "); 1321 | if (ejtag_version == 0) printf("1 or 2.0\n"); 1322 | else if (ejtag_version == 1) printf("2.5\n"); 1323 | else if (ejtag_version == 2) printf("2.6\n"); 1324 | else if (ejtag_version == 3) printf("3.1\n"); 1325 | else printf("Unknown (%d is a reserved value)\n", ejtag_version); 1326 | 1327 | // EJTAG DMA Support 1328 | USE_DMA = !(features & (1 << 14)); 1329 | printf(" - EJTAG DMA Support ... : %s\n", USE_DMA ? "Yes" : "No"); 1330 | printf( " - EJTAG Implementation flags:%s%s%s%s%s%s%s\n", 1331 | (features & (1 << 28)) ? " R3k" : " R4k", 1332 | (features & (1 << 24)) ? " DINTsup" : "", 1333 | (features & (1 << 22)) ? " ASID_8" : "", 1334 | (features & (1 << 21)) ? " ASID_6" : "", 1335 | (features & (1 << 16)) ? " MIPS16" : "", 1336 | (features & (1 << 14)) ? " NoDMA" : "", 1337 | (features & (1 )) ? " MIPS64" : " MIPS32" ); 1338 | 1339 | if (force_dma) 1340 | { 1341 | USE_DMA = 1; 1342 | printf(" *** DMA Mode Forced On ***\n"); 1343 | } 1344 | if (force_nodma) 1345 | { 1346 | USE_DMA = 0; 1347 | printf(" *** DMA Mode Forced Off ***\n"); 1348 | } 1349 | 1350 | printf("\n"); 1351 | } 1352 | 1353 | 1354 | void chip_shutdown(void) 1355 | { 1356 | fflush(stdout); 1357 | test_reset(); 1358 | lpt_closeport(); 1359 | } 1360 | 1361 | void 1362 | cable_wait( void ) 1363 | { 1364 | if (!delay) 1365 | return; 1366 | 1367 | for (dcounter = 0; dcounter < delay; dcounter++); 1368 | 1369 | } 1370 | 1371 | 1372 | void unlock_bypass(void) 1373 | { 1374 | ejtag_write_h(FLASH_MEMORY_START + (0x555 << 1), 0x00900090 ); /* unlock bypass reset */ 1375 | ejtag_write_h(FLASH_MEMORY_START + (0x555 << 1), 0x00aa00aa ); /* unlock bypass */ 1376 | ejtag_write_h(FLASH_MEMORY_START + (0x2aa << 1), 0x00550055 ); 1377 | ejtag_write_h(FLASH_MEMORY_START + (0x555 << 1), 0x00200020 ); 1378 | printf("\nEntered Unlock Bypass mode->\n"); 1379 | } 1380 | 1381 | 1382 | void unlock_bypass_reset(void) 1383 | { 1384 | ejtag_write_h(FLASH_MEMORY_START + (0x555 << 1), 0x00900090 ); /* unlock bypass reset */ 1385 | ejtag_write_h(FLASH_MEMORY_START + (0x000), 0x00000000 ); 1386 | } 1387 | 1388 | void run_backup(char *filename, unsigned int start, unsigned int length) 1389 | { 1390 | unsigned int addr, data; 1391 | FILE *fd; 1392 | int counter = 0; 1393 | int percent_complete = 0; 1394 | char newfilename[128] = ""; 1395 | // int swp_endian = (cmd_type == CMD_TYPE_SPI); 1396 | time_t start_time = time(0); 1397 | time_t end_time, elapsed_seconds; 1398 | 1399 | struct tm* lt = localtime(&start_time); 1400 | char time_str[16]; 1401 | 1402 | sprintf(time_str, "%04d%02d%02d_%02d%02d%02d", 1403 | lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, 1404 | lt->tm_hour, lt->tm_min, lt->tm_sec 1405 | ); 1406 | 1407 | printf("*** You Selected to Backup the %s ***\n\n",filename); 1408 | 1409 | strcpy(newfilename,filename); 1410 | strcat(newfilename,".SAVED"); 1411 | if (issue_timestamp) 1412 | { 1413 | strcat(newfilename,"_"); 1414 | strcat(newfilename,time_str); 1415 | } 1416 | 1417 | fd = fopen(newfilename, "wb" ); 1418 | if (fd<=0) 1419 | { 1420 | fprintf(stderr,"Could not open %s for writing\n", newfilename); 1421 | exit(1); 1422 | } 1423 | 1424 | printf("=========================\n"); 1425 | printf("Backup Routine Started\n"); 1426 | printf("=========================\n"); 1427 | 1428 | printf("\nSaving %s to Disk...\n",newfilename); 1429 | for (addr=start; addr<(start+length); addr+=4) 1430 | { 1431 | counter += 4; 1432 | percent_complete = (counter * 100 / length); 1433 | if (!silent_mode) 1434 | if ((addr&0xF) == 0) printf("[%3d%% Backed Up] %08x: ", percent_complete, addr); 1435 | 1436 | data = ejtag_read(addr); 1437 | 1438 | 1439 | if (swap_endian) data = byteSwap_32(data); 1440 | fwrite( (unsigned char*) &data, 1, sizeof(data), fd); 1441 | 1442 | if (silent_mode) printf("%4d%% bytes = %d\r", percent_complete, counter); 1443 | else printf("%08x%c", data, (addr&0xF)==0xC?'\n':' '); 1444 | 1445 | fflush(stdout); 1446 | } 1447 | 1448 | 1449 | 1450 | fclose(fd); 1451 | 1452 | printf("Done (%s saved to Disk OK)\n\n",newfilename); 1453 | 1454 | printf("bytes written: %d\n", counter); 1455 | 1456 | printf("=========================\n"); 1457 | printf("Backup Routine Complete\n"); 1458 | printf("=========================\n"); 1459 | 1460 | time(&end_time); 1461 | elapsed_seconds = difftime(end_time, start_time); 1462 | printf("elapsed time: %d seconds\n", (int)elapsed_seconds); 1463 | } 1464 | 1465 | void run_erase(char *filename, unsigned int start, unsigned int length) 1466 | { 1467 | time_t start_time = time(0); 1468 | time_t end_time, elapsed_seconds; 1469 | 1470 | printf("*** You Selected to Erase the %s ***\n\n",filename); 1471 | 1472 | printf("=========================\n"); 1473 | printf("Erasing Routine Started\n"); 1474 | printf("=========================\n"); 1475 | 1476 | sflash_erase_area(start,length); 1477 | sflash_reset(); 1478 | 1479 | printf("=========================\n"); 1480 | printf("Erasing Routine Complete\n"); 1481 | printf("=========================\n"); 1482 | 1483 | time(&end_time); 1484 | elapsed_seconds = difftime(end_time, start_time); 1485 | printf("elapsed time: %d seconds\n", (int)elapsed_seconds); 1486 | } 1487 | 1488 | 1489 | void identify_flash_part(void) 1490 | { 1491 | flash_chip_type* flash_chip = flash_chip_list; 1492 | flash_area_type* flash_area = flash_area_list; 1493 | 1494 | // Important for these to initialize to zero 1495 | block_addr = 0; 1496 | block_total = 0; 1497 | flash_size = 0; 1498 | cmd_type = 0; 1499 | strcpy(flash_part,""); 1500 | 1501 | /* Spansion ID workaround (kb1klk) 30 Dec 2007 1502 | 1503 | Vendor ID altered to 017E to avoid ambiguity in lookups. 1504 | Spansion uses vend 0001 dev 227E for numerous chips. 1505 | This code reads device SubID from its address and combine this into 1506 | the unique devid that will be used in the lookup table. */ 1507 | 1508 | if (((vendid & 0x00ff) == 0x0001) && (devid == 0x227E)) 1509 | { 1510 | unsigned int devsubid_m, devsubid_l; 1511 | vendid = 0x017E; 1512 | devsubid_m = 0x00ff & ejtag_read_h(FLASH_MEMORY_START+0x1C); // sub ID step 1 1513 | devsubid_l = 0x00ff & ejtag_read_h(FLASH_MEMORY_START+0x1E); // sub ID step 2 1514 | devid = (0x0100 * devsubid_m) + (0x0000 + devsubid_l); 1515 | } 1516 | 1517 | 1518 | /* WinBond extended ID query - 27 Jan 2008 */ 1519 | 1520 | if (((vendid & 0x00ff) == 0x00DA) && ((devid & 0x00ff) == 0x007E)) 1521 | { 1522 | unsigned int devsubid_m, devsubid_l; 1523 | vendid = 0xDA7E; 1524 | devsubid_m = 0x00ff & ejtag_read_h(FLASH_MEMORY_START+0x1C); // sub ID step 1 1525 | devsubid_l = 0x00ff & ejtag_read_h(FLASH_MEMORY_START+0x1E); // sub ID step 2 1526 | devid = (0x0100 * devsubid_m) + (0x0000 + devsubid_l); 1527 | } 1528 | 1529 | 1530 | 1531 | while (flash_chip->vendid) 1532 | { 1533 | if ((flash_chip->vendid == vendid) && (flash_chip->devid == devid)) 1534 | { 1535 | flash_size = flash_chip->flash_size; 1536 | cmd_type = flash_chip->cmd_type; 1537 | strcpy(flash_part, flash_chip->flash_part); 1538 | 1539 | if (strcasecmp(AREA_NAME,"CUSTOM")==0) 1540 | { 1541 | FLASH_MEMORY_START = selected_window; 1542 | } 1543 | else 1544 | { 1545 | switch (proc_id) 1546 | { 1547 | 1548 | case IXP425_266: 1549 | case IXP425_400: 1550 | // case IXP425_533: 1551 | // FLASH_MEMORY_START = 0x50000000; 1552 | // break; 1553 | case ARM_940T: 1554 | FLASH_MEMORY_START = 0x00400000; 1555 | break; 1556 | case 0x0635817F: 1557 | FLASH_MEMORY_START = 0x1F000000; 1558 | break; 1559 | // case ATH_PROC: 1560 | // FLASH_MEMORY_START = 0xA8000000; 1561 | // break; 1562 | 1563 | case 0x0000100F: //Ti AR7 1564 | FLASH_MEMORY_START = 0x90000000; 1565 | break; 1566 | 1567 | default: 1568 | if (flash_size >= size8MB ) 1569 | { 1570 | 1571 | FLASH_MEMORY_START = 0x1C000000; 1572 | } 1573 | else 1574 | { 1575 | 1576 | FLASH_MEMORY_START = 0x1FC00000; 1577 | } 1578 | 1579 | } 1580 | } 1581 | 1582 | 1583 | 1584 | if (proc_id == 0x00000001) 1585 | { 1586 | 1587 | if ((strcasecmp(AREA_NAME,"CFE")==0) && flash_size >= size8MB) 1588 | strcpy(AREA_NAME, "AR-CFE"); 1589 | 1590 | if ((strcasecmp(AREA_NAME,"NVRAM")==0) && flash_size >= size8MB) 1591 | strcpy(AREA_NAME, "AR-NVRAM"); 1592 | 1593 | if ((strcasecmp(AREA_NAME,"KERNEL")==0) && flash_size >= size8MB) 1594 | strcpy(AREA_NAME, "AR-KERNEL"); 1595 | 1596 | if ((strcasecmp(AREA_NAME,"WHOLEFLASH")==0) && flash_size >= size8MB) 1597 | strcpy(AREA_NAME, "AR-WHOLEFLASH"); 1598 | 1599 | if ((strcasecmp(AREA_NAME,"BSP")==0) && flash_size >= size8MB) 1600 | strcpy(AREA_NAME, "AR-BSP"); 1601 | 1602 | if ((strcasecmp(AREA_NAME,"RED")==0) && flash_size >= size8MB) 1603 | strcpy(AREA_NAME, "AR-RED"); 1604 | } 1605 | 1606 | 1607 | while (flash_area->chip_size) 1608 | { 1609 | if ((flash_area->chip_size == flash_size) && (strcasecmp(flash_area->area_name, AREA_NAME)==0)) 1610 | { 1611 | 1612 | strcat(AREA_NAME,".BIN"); 1613 | AREA_START = flash_area->area_start; 1614 | AREA_LENGTH = flash_area->area_length; 1615 | break; 1616 | } 1617 | flash_area++; 1618 | } 1619 | 1620 | if (strcasecmp(AREA_NAME,"CUSTOM")==0) 1621 | { 1622 | strcat(AREA_NAME,".BIN"); 1623 | FLASH_MEMORY_START = selected_window; 1624 | AREA_START = selected_start; 1625 | AREA_LENGTH = selected_length; 1626 | } 1627 | 1628 | if (flash_chip->region1_num) define_block(flash_chip->region1_num, flash_chip->region1_size); 1629 | if (flash_chip->region2_num) define_block(flash_chip->region2_num, flash_chip->region2_size); 1630 | if (flash_chip->region3_num) define_block(flash_chip->region3_num, flash_chip->region3_size); 1631 | if (flash_chip->region4_num) define_block(flash_chip->region4_num, flash_chip->region4_size); 1632 | 1633 | sflash_reset(); 1634 | 1635 | printf("Done\n\n"); 1636 | printf("Flash Vendor ID: "); 1637 | ShowData(vendid); 1638 | printf("Flash Device ID: "); 1639 | ShowData(devid); 1640 | if (selected_fc != 0) 1641 | printf("*** Manually Selected a %s Flash Chip ***\n\n", flash_part); 1642 | else 1643 | printf("*** Found a %s Flash Chip ***\n\n", flash_part); 1644 | 1645 | printf(" - Flash Chip Window Start .... : %08x\n", FLASH_MEMORY_START); 1646 | printf(" - Flash Chip Window Length ... : %08x\n", flash_size); 1647 | printf(" - Selected Area Start ........ : %08x\n", AREA_START); 1648 | printf(" - Selected Area Length ....... : %08x\n\n", AREA_LENGTH); 1649 | 1650 | break; 1651 | } 1652 | flash_chip++; 1653 | } 1654 | 1655 | } 1656 | 1657 | void define_block(unsigned int block_count, unsigned int block_size) 1658 | { 1659 | unsigned int i; 1660 | 1661 | if (block_addr == 0) block_addr = FLASH_MEMORY_START; 1662 | 1663 | for (i = 1; i <= block_count; i++) 1664 | { 1665 | block_total++; 1666 | blocks[block_total] = block_addr; 1667 | block_addr = block_addr + block_size; 1668 | 1669 | } 1670 | } 1671 | 1672 | 1673 | void sflash_config(void) 1674 | { 1675 | flash_chip_type* flash_chip = flash_chip_list; 1676 | int counter = 0; 1677 | 1678 | printf("\nManual Flash Selection ... "); 1679 | 1680 | while (flash_chip->vendid) 1681 | { 1682 | counter++; 1683 | if (counter == selected_fc) 1684 | { 1685 | vendid = flash_chip->vendid; 1686 | devid = flash_chip->devid; 1687 | identify_flash_part(); 1688 | break; 1689 | } 1690 | flash_chip++; 1691 | } 1692 | 1693 | if (strcasecmp(flash_part,"")==0) 1694 | printf("*** Unknown or NO Flash Chip Selected ***\n"); 1695 | 1696 | } 1697 | 1698 | unsigned char ATstatus_reg(void) 1699 | { 1700 | unsigned char status; 1701 | 1702 | ejtag_write(0x1fc00000, 0x57); 1703 | status = ejtag_read(0x1fc00000 &0x80); 1704 | printf("id bit = 0x%08x\n", status&0x3c); 1705 | ShowData(status); 1706 | return status; 1707 | } 1708 | 1709 | unsigned int ATready(void) 1710 | { 1711 | 1712 | int status; 1713 | for (;;) 1714 | { 1715 | status = ATstatus_reg(); 1716 | status = (status&0xF<<7); 1717 | // printf("status1 = 0x%08x\n", status); 1718 | // ShowData(status); 1719 | 1720 | if (status != 0x80) 1721 | { 1722 | // printf("Status BSY 0x%08x\n", status); 1723 | status = 0; 1724 | tnano(10000); 1725 | 1726 | } 1727 | 1728 | if (status == 0x80) /* RDY/nBSY */ 1729 | 1730 | 1731 | return status; 1732 | 1733 | } 1734 | } 1735 | 1736 | 1737 | void mscan(void) 1738 | { 1739 | unsigned int addr = 0x18000000, val=0, i; 1740 | 1741 | for (i=0; i < 20000; i++) 1742 | { 1743 | 1744 | // val = ((ejtag_read(addr)) &CID_ID_MASK); 1745 | val = ejtag_dma_read(addr); 1746 | // if (val != NULL && val != 0x0); 1747 | printf("data 0x%08x addr 0x%08x\n", val, addr); 1748 | addr += 0x100; 1749 | 1750 | 1751 | } 1752 | 1753 | } 1754 | 1755 | 1756 | void isbrcm(void) 1757 | { 1758 | /* 1759 | if ((proc_id & 0xfff) == 0x17f) 1760 | { 1761 | struct chipcregs *cc; 1762 | 1763 | uint32_t reg; 1764 | unsigned long osh = 0x18000000; //0x18000000; 1765 | cc = (chipcregs_t *)osh; 1766 | 1767 | reg = ejtag_read((uintptr_t) &cc->chipid) &CID_ID_MASK; 1768 | printf("\n\nChip id %x\n", reg); 1769 | 1770 | reg = ejtag_read((uintptr_t) &cc->chipid) &CID_REV_MASK; 1771 | reg = (reg >> CID_REV_SHIFT); 1772 | printf("Chip Rev %x\n", reg); 1773 | 1774 | reg = ejtag_read((uintptr_t) &cc->chipid) &CID_PKG_MASK; 1775 | reg = (reg >> CID_PKG_SHIFT); 1776 | printf("Package Options %x\n", reg); 1777 | 1778 | reg = ejtag_read((uintptr_t) &cc->chipid) &CID_CC_MASK; 1779 | reg = (reg >> CID_CC_SHIFT); 1780 | printf("Number of Cores %x\n", reg ); 1781 | 1782 | reg = ejtag_read((uintptr_t) &cc->chipid) & 0x00007000; 1783 | reg = ((reg >> 8) | 0x0000000F); 1784 | printf("Core Revision %x\n", reg); 1785 | 1786 | reg = ejtag_read((uintptr_t) &cc->chipid) & 0x00008FF0; 1787 | printf("Core Type %x\n", reg); 1788 | 1789 | reg = ejtag_read((uintptr_t) &cc->chipid) & 0xFFFF0000; 1790 | printf("Core Vendor ID %x\n", reg); 1791 | 1792 | reg = ejtag_read((uintptr_t) &cc->capabilities) &CC_CAP_FLASH_MASK; 1793 | printf("Flash Type %x\n", reg); 1794 | 1795 | printf("REG = %lu CC = %lu \n", sizeof(reg ), sizeof(cc->chipid) ); 1796 | 1797 | switch (reg) 1798 | { 1799 | case FLASH_NONE: 1800 | printf("Flash Type = FLASH_NONE\n"); 1801 | break; 1802 | case SFLASH_ST: 1803 | printf("Flash Type = SFLASH_ST\n"); 1804 | break; 1805 | case SFLASH_AT: 1806 | printf("Flash Type = FLASH_AT\n"); 1807 | break; 1808 | case PFLASH: 1809 | printf("Flash Type = PFLASH\n"); 1810 | break; 1811 | default: 1812 | break; 1813 | } 1814 | 1815 | reg = ejtag_read((unsigned long) &cc->capabilities) &CC_CAP_MIPSEB; 1816 | if (reg == 0) 1817 | { 1818 | printf("Endian Type is LE %x\n", reg); 1819 | } 1820 | else 1821 | printf("Endian Type is BE %x\n", reg); 1822 | 1823 | reg = ejtag_read((unsigned long) &cc->capabilities) &CC_CAP_PLL_MASK; 1824 | printf("PLL Type %08x\n", reg); 1825 | 1826 | } 1827 | */ 1828 | if ((proc_id & 0x00000fff) == 0x17f) 1829 | { 1830 | bcmproc = 1; 1831 | 1832 | spi_flash_read = BRCM_SPI_READ; 1833 | spi_flash_mmr = BRCM_SPI_MMR; 1834 | spi_flash_mmr_size = BRCM_SPI_MMR_SIZE; 1835 | spi_flash_ctl = BRCM_SPI_CTL; 1836 | spi_flash_opcode = BRCM_SPI_OPCODE; 1837 | spi_flash_data = BRCM_SPI_DATA; 1838 | spi_ctl_start = BRCM_SPI_CTL_START; 1839 | spi_ctl_busy = BRCM_SPI_CTL_BUSY; 1840 | 1841 | 1842 | } 1843 | else 1844 | { 1845 | spi_flash_read = AR531XPLUS_SPI_READ; 1846 | spi_flash_mmr = AR531XPLUS_SPI_MMR; 1847 | spi_flash_mmr_size = AR531XPLUS_SPI_MMR_SIZE; 1848 | spi_flash_ctl = AR531XPLUS_SPI_CTL; 1849 | spi_flash_opcode = AR531XPLUS_SPI_OPCODE; 1850 | spi_flash_data = AR531XPLUS_SPI_DATA; 1851 | spi_ctl_start = AR_SPI_CTL_START; 1852 | spi_ctl_busy = AR_SPI_CTL_BUSY; 1853 | } 1854 | 1855 | if (Flash_DEBUG) 1856 | { 1857 | printf("spi_flash_read 0x%08x\n", spi_flash_read); 1858 | printf("spi_flash_mmr 0x%08x\n", spi_flash_mmr); 1859 | printf("spi_flash_mmr_size 0x%08x\n", spi_flash_mmr_size); 1860 | printf("spi_flash_ctl 0x%08x\n", spi_flash_ctl); 1861 | printf("spi_flash_opcode 0x%08x\n", spi_flash_opcode); 1862 | printf("spi_flash_data 0x%08x\n", spi_flash_data); 1863 | printf("spi_ctl_start 0x%08x\n", spi_ctl_start ); 1864 | printf("spi_ctl_busy 0x%08x\n", spi_ctl_busy); 1865 | } 1866 | } 1867 | 1868 | 1869 | int spiflash_poll(void) 1870 | { 1871 | int reg, finished; 1872 | 1873 | /* Check for ST Write In Progress bit */ 1874 | spiflash_sendcmd(SPI_RD_STATUS); 1875 | reg = ejtag_read(spi_flash_data); 1876 | if (!(reg & SPI_STATUS_WIP)) 1877 | { 1878 | finished = TRUE; 1879 | printf("REG SPIFLASH_POLL 0x%08x\n", reg); 1880 | } 1881 | while (!finished); 1882 | return 0; 1883 | } 1884 | 1885 | 1886 | uint32_t spiflash_regread32(int reg) 1887 | { 1888 | 1889 | uint32_t data = ejtag_read( spi_flash_mmr + reg ); 1890 | if (Flash_DEBUG) 1891 | printf("REGREAD32 data 0x%08x spi_flash_mmr 0x%08x reg 0x%08x\n", data, spi_flash_mmr, reg ); 1892 | 1893 | return data; 1894 | } 1895 | 1896 | static void spiflash_regwrite32(int reg, uint32_t data) 1897 | { 1898 | 1899 | ejtag_write(spi_flash_mmr + reg, data ); 1900 | if (Flash_DEBUG) 1901 | printf("REG 0x%08x REGWRITE32 0x%08x\n", reg, data); 1902 | 1903 | return; 1904 | } 1905 | 1906 | 1907 | uint32_t spiflash_sendcmd(int op) 1908 | { 1909 | uint32_t reg, mask; 1910 | struct opcodes *ptr_opcode; 1911 | 1912 | ptr_opcode = &stm_opcodes[op]; 1913 | 1914 | if (bcmproc) 1915 | ejtag_write(0x18000040, 0x0000); 1916 | 1917 | 1918 | /* wait for CPU spiflash activity. */ 1919 | do 1920 | { 1921 | reg = spiflash_regread32(spi_flash_ctl); 1922 | 1923 | } 1924 | while (reg & spi_ctl_busy); 1925 | 1926 | /* send the command */ 1927 | 1928 | spiflash_regwrite32(spi_flash_opcode, ptr_opcode->code); 1929 | 1930 | if (Flash_DEBUG) 1931 | printf("SPI_FLASH_OPCODE 0x%08x PTR_OPCODE 0x%08x\n", spi_flash_opcode, ptr_opcode->code); 1932 | 1933 | if (bcmproc) 1934 | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->code | spi_ctl_start; 1935 | else 1936 | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | (ptr_opcode->rx_cnt << 4)| spi_ctl_start; 1937 | 1938 | spiflash_regwrite32(spi_flash_ctl, reg); 1939 | 1940 | if (Flash_DEBUG) 1941 | printf("SPI_FLASH_CTL SEND -> 0x%08x reg 0x%08x\n", spi_flash_ctl, reg); 1942 | 1943 | 1944 | /* wait for CPU spiflash activity */ 1945 | do 1946 | { 1947 | reg = spiflash_regread32(spi_flash_ctl); 1948 | 1949 | } 1950 | while (reg & spi_ctl_busy); 1951 | 1952 | if (ptr_opcode->rx_cnt > 0) 1953 | { 1954 | reg = (uint32_t) spiflash_regread32(spi_flash_data); 1955 | 1956 | switch (ptr_opcode->rx_cnt) 1957 | { 1958 | case 1: 1959 | mask = 0x000000ff; 1960 | break; 1961 | case 2: 1962 | mask = 0x0000ffff; 1963 | break; 1964 | case 3: 1965 | mask = 0x00ffffff; 1966 | break; 1967 | default: 1968 | mask = 0xffffffff; 1969 | break; 1970 | } 1971 | reg &= mask; 1972 | } 1973 | else 1974 | { 1975 | reg = 0; 1976 | } 1977 | 1978 | return reg; 1979 | } 1980 | 1981 | int spi_chiperase(uint32_t offset) 1982 | { 1983 | 1984 | ejtag_write(0x18000040, 0x0000); 1985 | 1986 | spiflash_sendcmd(SPI_WRITE_ENABLE); 1987 | 1988 | ejtag_write(BRCM_FLASHADDRESS, offset); 1989 | 1990 | ejtag_write(0x18000040, 0x800000c7); 1991 | 1992 | return 0; 1993 | 1994 | } 1995 | 1996 | 1997 | static int spiflash_erase_block( uint32_t addr ) 1998 | { 1999 | 2000 | struct opcodes *ptr_opcode; 2001 | uint32_t temp, reg; 2002 | int finished = FALSE; 2003 | 2004 | /* We are going to do 'sector erase', do 'write enable' first. */ 2005 | if (bcmproc) 2006 | ptr_opcode = &stm_opcodes[BCM_SPI_SECTOR_ERASE]; 2007 | else 2008 | ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 2009 | 2010 | if (bcmproc) 2011 | ejtag_write(0x18000040, 0x0000); 2012 | 2013 | spiflash_sendcmd(SPI_WRITE_ENABLE); 2014 | 2015 | /* we are not really waiting for CPU spiflash activity, just need the value of the register. */ 2016 | 2017 | do 2018 | { 2019 | reg = spiflash_regread32(spi_flash_ctl); 2020 | 2021 | } 2022 | while (reg & spi_ctl_busy); 2023 | 2024 | /* send our command */ 2025 | if (bcmproc) 2026 | temp = ((uint32_t) addr) | (uint32_t)(ptr_opcode->code); 2027 | else 2028 | temp = ((uint32_t) addr << 8) | (uint32_t)(ptr_opcode->code); 2029 | 2030 | spiflash_regwrite32(spi_flash_opcode, temp); 2031 | 2032 | if (bcmproc) 2033 | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->code | spi_ctl_start; 2034 | else 2035 | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | spi_ctl_start; 2036 | 2037 | spiflash_regwrite32(spi_flash_ctl, reg ); 2038 | 2039 | if (bcmproc) 2040 | ejtag_write(0x18000040, 0x0000); 2041 | 2042 | /* wait for CPU spiflash activity */ 2043 | 2044 | 2045 | do 2046 | { 2047 | reg = spiflash_regread32(spi_flash_ctl); 2048 | 2049 | } 2050 | while (reg & spi_ctl_busy); 2051 | 2052 | /* wait for 'write in progress' to clear */ 2053 | do 2054 | { 2055 | if (bcmproc) 2056 | reg = spiflash_sendcmd(BCM_SPI_RD_STATUS); 2057 | else 2058 | reg = spiflash_sendcmd(SPI_RD_STATUS); 2059 | if (!(reg & SPI_STATUS_WIP)) finished = TRUE; 2060 | } 2061 | while (!finished); 2062 | 2063 | return (0); 2064 | } 2065 | 2066 | void spiflash_write_word(uint32_t addr, uint32_t data) 2067 | { 2068 | int finished; 2069 | uint32_t reg, opcode; 2070 | 2071 | 2072 | if (bcmproc) 2073 | { 2074 | ejtag_write(spi_flash_ctl, 0x000); 2075 | spiflash_sendcmd(BCM_SPI_WRITE_ENABLE); 2076 | } 2077 | else 2078 | spiflash_sendcmd(SPI_WRITE_ENABLE); 2079 | 2080 | /* we are not really waiting for CPU spiflash activity, just need the value of the register. */ 2081 | do 2082 | { 2083 | reg = spiflash_regread32(spi_flash_ctl); 2084 | 2085 | } 2086 | while (reg & spi_ctl_busy); 2087 | 2088 | /* send write command */ 2089 | 2090 | spiflash_regwrite32(spi_flash_data, data); 2091 | 2092 | if (bcmproc) 2093 | opcode = (addr); 2094 | else 2095 | opcode = STM_OP_PAGE_PGRM | (addr << 8); 2096 | 2097 | spiflash_regwrite32(spi_flash_opcode, opcode); 2098 | 2099 | if (bcmproc) 2100 | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x0402 | spi_ctl_start; 2101 | else 2102 | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (4 + 4) | spi_ctl_start; 2103 | 2104 | spiflash_regwrite32(spi_flash_ctl, reg); 2105 | 2106 | if (Flash_DEBUG) 2107 | printf("spi_flash_ctl 0x%08x reg 0x%08x\n", spi_flash_ctl, reg); 2108 | 2109 | finished = 0; 2110 | 2111 | /* wait CPU spi activity */ 2112 | do 2113 | { 2114 | reg = spiflash_regread32(spi_flash_ctl); 2115 | 2116 | 2117 | } 2118 | while (reg & spi_ctl_busy); 2119 | 2120 | do 2121 | { 2122 | if (bcmproc) 2123 | reg = spiflash_sendcmd(BCM_SPI_RD_STATUS); 2124 | else 2125 | reg = spiflash_sendcmd(SPI_RD_STATUS); 2126 | 2127 | if (!(reg & SPI_STATUS_WIP)) 2128 | { 2129 | finished = TRUE; 2130 | } 2131 | } 2132 | while (!finished); 2133 | } 2134 | 2135 | 2136 | void run_flash(char *filename, unsigned int start, unsigned int length) 2137 | { 2138 | unsigned int addr, data ; 2139 | FILE *fd ; 2140 | int counter = 0; 2141 | int percent_complete = 0; 2142 | time_t start_time = time(0); 2143 | time_t end_time, elapsed_seconds; 2144 | 2145 | printf("*** You Selected to Flash the %s ***\n\n",filename); 2146 | 2147 | fd=fopen(filename, "rb" ); 2148 | if (fd<=0) 2149 | { 2150 | fprintf(stderr,"Could not open %s for reading\n", filename); 2151 | exit(1); 2152 | } 2153 | 2154 | printf("=========================\n"); 2155 | printf("Flashing Routine Started\n"); 2156 | printf("=========================\n"); 2157 | 2158 | if (issue_erase) sflash_erase_area(start,length); 2159 | 2160 | if (bypass) 2161 | { 2162 | unlock_bypass(); 2163 | } 2164 | 2165 | printf("\nLoading %s to Flash Memory...\n",filename); 2166 | for (addr=start; addr<(start+length); addr+=4) 2167 | { 2168 | counter += 4; 2169 | percent_complete = (counter * 100 / length); 2170 | if (!silent_mode) 2171 | if ((addr&0xF) == 0) printf("[%3d%% Flashed] %08x: ", percent_complete, addr); 2172 | 2173 | fread( (unsigned char*) &data, 1,sizeof(data), fd); 2174 | 2175 | // Erasing Flash Sets addresses to 0xFF's so we can avoid writing these (for speed) 2176 | if (issue_erase) 2177 | { 2178 | if (!(data == 0xFFFFFFFF)) 2179 | sflash_write_word(addr, data); 2180 | } 2181 | else 2182 | sflash_write_word(addr, data); // Otherwise we gotta flash it all 2183 | 2184 | 2185 | // original if (silent_mode) printf("%4d%% bytes = %d\r", percent_complete, counter); 2186 | if (silent_mode) printf("%4d%% bytes = %d (%08x)@(%08x)=%08x\r", percent_complete, counter, counter, addr, data); 2187 | else printf("%08x%c", data, (addr&0xF)==0xC?'\n':' '); 2188 | 2189 | 2190 | fflush(stdout); 2191 | data = 0xFFFFFFFF; // This is in case file is shorter than expected length 2192 | } 2193 | 2194 | fclose(fd); 2195 | printf("Done (%s loaded into Flash Memory OK)\n\n",filename); 2196 | 2197 | sflash_reset(); 2198 | 2199 | 2200 | printf("=========================\n"); 2201 | printf("Flashing Routine Complete\n"); 2202 | printf("=========================\n"); 2203 | 2204 | time(&end_time); 2205 | elapsed_seconds = difftime(end_time, start_time); 2206 | printf("elapsed time: %d seconds\n", (int)elapsed_seconds); 2207 | } 2208 | 2209 | void run_load(char *filename, unsigned int start) 2210 | { 2211 | unsigned int addr, data ; 2212 | FILE *fd ; 2213 | int counter = 0; 2214 | int percent_complete = 0; 2215 | unsigned int length = 0; 2216 | time_t start_time = time(0); 2217 | time_t end_time, elapsed_seconds; 2218 | 2219 | printf("*** You Selected to program the %s ***\n\n",filename); 2220 | 2221 | fd=fopen(filename, "rb" ); 2222 | if (fd<=0) 2223 | { 2224 | fprintf(stderr,"Could not open %s for reading\n", filename); 2225 | exit(1); 2226 | } 2227 | 2228 | // get file size 2229 | fseek(fd, 0, SEEK_END); 2230 | length = ftell(fd); 2231 | fseek(fd, 0, SEEK_SET); 2232 | 2233 | 2234 | printf("===============================\n"); 2235 | printf("Programming RAM Routine Started\n"); 2236 | printf("===============================\n"); 2237 | 2238 | printf("\nLoading %s to RAM...\n",filename); 2239 | for (addr=start; addr<(start+length); addr+=4) 2240 | { 2241 | counter += 4; 2242 | percent_complete = (counter * 100 / length); 2243 | if (!silent_mode) 2244 | if ((addr&0xF) == 0) printf("[%3d%%] %08x: ", percent_complete, addr); 2245 | 2246 | fread( (unsigned char*) &data, 1,sizeof(data), fd); 2247 | ejtag_write(addr, data); 2248 | 2249 | if (silent_mode) printf("%4d%% bytes = %d (%08x)@(%08x)=%08x\r", percent_complete, counter, counter, addr, data); 2250 | else printf("%08x%c", data, (addr&0xF)==0xC?'\n':' '); 2251 | 2252 | fflush(stdout); 2253 | data = 0xFFFFFFFF; // This is in case file is shorter than expected length 2254 | } 2255 | fclose(fd); 2256 | printf("Done (%s loaded into Memory OK)\n\n",filename); 2257 | 2258 | sflash_reset(); 2259 | 2260 | 2261 | printf("================================\n"); 2262 | printf("Programming RAM Routine Complete\n"); 2263 | printf("================================\n"); 2264 | 2265 | time(&end_time); 2266 | elapsed_seconds = difftime(end_time, start_time); 2267 | printf("elapsed time: %d seconds\n", (int)elapsed_seconds); 2268 | 2269 | /* 2270 | printf("Resuming Processor ... "); 2271 | set_instr(INSTR_CONTROL); 2272 | ReadWriteData((PRACC | PROBEN | PROBTRAP) & ~JTAGBRK ); 2273 | if (ReadWriteData(PRACC | PROBEN | PROBTRAP) & BRKST) 2274 | printf(" ... "); 2275 | else 2276 | printf(" ... "); 2277 | 2278 | ReadWriteData(PRRST | PERRST); 2279 | printf("Done\n"); 2280 | */ 2281 | } 2282 | 2283 | 2284 | void sflash_probe(void) 2285 | { 2286 | int retries = 0; 2287 | 2288 | 2289 | if (strcasecmp(AREA_NAME,"CUSTOM")==0) 2290 | { 2291 | FLASH_MEMORY_START = selected_window; 2292 | } 2293 | else 2294 | { 2295 | switch (proc_id) 2296 | { 2297 | 2298 | case IXP425_266: 2299 | case IXP425_400: 2300 | // case IXP425_533: 2301 | // FLASH_MEMORY_START = 0x50000000; 2302 | // break; 2303 | case ARM_940T: 2304 | FLASH_MEMORY_START = 0x00400000; 2305 | break; 2306 | case 0x0635817F: 2307 | FLASH_MEMORY_START = 0x1F000000; 2308 | break; 2309 | // case ATH_PROC: 2310 | // FLASH_MEMORY_START = 0xA8000000; 2311 | // break; 2312 | 2313 | case 0x0000100F: //Ti AR7 2314 | FLASH_MEMORY_START = 0x90000000; 2315 | break; 2316 | 2317 | default: 2318 | if (flash_size >= size8MB ) 2319 | { 2320 | 2321 | FLASH_MEMORY_START = 0x1c000000; 2322 | } 2323 | else 2324 | { 2325 | 2326 | FLASH_MEMORY_START = 0x1FC00000; 2327 | } 2328 | 2329 | } 2330 | } 2331 | 2332 | printf("\nProbing Flash at (Flash Window: 0x%08x) ... \n", FLASH_MEMORY_START); 2333 | 2334 | again: 2335 | 2336 | strcpy(flash_part,""); 2337 | 2338 | // Probe using cmd_type for AMD 2339 | 2340 | if (strcasecmp(flash_part,"")==0) 2341 | { 2342 | 2343 | cmd_type = CMD_TYPE_AMD; 2344 | sflash_reset(); 2345 | 2346 | ejtag_write_h(FLASH_MEMORY_START + (0x555 << 1), 0x00AA00AA); 2347 | ejtag_write_h(FLASH_MEMORY_START + (0x2AA << 1), 0x00550055); 2348 | ejtag_write_h(FLASH_MEMORY_START + (0x555 << 1), 0x00900090); 2349 | vendid = ejtag_read_h(FLASH_MEMORY_START); 2350 | devid = ejtag_read_h(FLASH_MEMORY_START+2); 2351 | 2352 | if (Flash_DEBUG) 2353 | { 2354 | printf("\nDebug AMD Vendid : "); 2355 | ShowData (vendid); 2356 | printf("Debug AMD Devdid : "); 2357 | ShowData (devid); 2358 | 2359 | } 2360 | 2361 | identify_flash_part(); 2362 | } 2363 | 2364 | 2365 | if (strcasecmp(flash_part,"")==0) 2366 | { 2367 | 2368 | cmd_type = CMD_TYPE_SST; 2369 | sflash_reset(); 2370 | ejtag_write_h(FLASH_MEMORY_START + (0x5555 << 1), 0x00AA00AA); 2371 | ejtag_write_h(FLASH_MEMORY_START + (0x2AAA << 1), 0x00550055); 2372 | ejtag_write_h(FLASH_MEMORY_START + (0x5555 << 1), 0x00900090); 2373 | vendid = ejtag_read_h(FLASH_MEMORY_START); 2374 | devid = ejtag_read_h(FLASH_MEMORY_START+2); 2375 | 2376 | if (Flash_DEBUG) 2377 | { 2378 | printf("\nDebug SST Vendid : "); 2379 | ShowData (vendid); 2380 | printf("Debug SST Devdid : "); 2381 | ShowData (devid); 2382 | 2383 | } 2384 | 2385 | identify_flash_part(); 2386 | 2387 | } 2388 | 2389 | 2390 | // Probe using cmd_type for BSC & SCS 2391 | 2392 | if (strcasecmp(flash_part,"")==0) 2393 | { 2394 | 2395 | cmd_type = CMD_TYPE_BSC; 2396 | sflash_reset(); 2397 | 2398 | ejtag_write_h(FLASH_MEMORY_START, 0x00900090); 2399 | vendid = ejtag_read(FLASH_MEMORY_START); 2400 | devid = ejtag_read(FLASH_MEMORY_START+2); 2401 | 2402 | 2403 | if (Flash_DEBUG) 2404 | { 2405 | printf("\nDebug BSC-SCS Vendid :"); 2406 | ShowData (vendid); 2407 | printf("Debug BCS-SCS Devdid :"); 2408 | ShowData (devid); 2409 | 2410 | } 2411 | 2412 | identify_flash_part(); 2413 | } 2414 | 2415 | 2416 | if (strcasecmp(flash_part,"")==0) 2417 | { 2418 | int id; 2419 | 2420 | cmd_type = CMD_TYPE_SPI; 2421 | 2422 | if (bcmproc) 2423 | { 2424 | id = spiflash_sendcmd(BCM_SPI_RD_ID); 2425 | //id2 = spiflash_sendcmd(BCM_SPI_RD_RES); 2426 | 2427 | } 2428 | else 2429 | id = spiflash_sendcmd(SPI_RD_ID); 2430 | 2431 | id <<= 8; 2432 | id = byteSwap_32(id); 2433 | vendid = id >> 16; 2434 | devid = id & 0x0000ffff; 2435 | 2436 | if (Flash_DEBUG) 2437 | { 2438 | printf("\nDebug SPI id : "); 2439 | ShowData (id); 2440 | printf("\nDebug SPI Vendid : "); 2441 | ShowData (vendid); 2442 | printf("Debug SPI Devdid : "); 2443 | ShowData (devid); 2444 | 2445 | 2446 | } 2447 | 2448 | identify_flash_part(); 2449 | } 2450 | 2451 | 2452 | if (strcasecmp(flash_part,"")==0) 2453 | { 2454 | if (retries--) 2455 | goto again; 2456 | else 2457 | { 2458 | printf("Done\n\n"); 2459 | printf("*** Unknown or NO Flash Chip Detected ***"); 2460 | } 2461 | } 2462 | return; 2463 | } 2464 | 2465 | void sflash_poll(unsigned int addr, unsigned int data) 2466 | { 2467 | if ((cmd_type == CMD_TYPE_BSC) || (cmd_type == CMD_TYPE_SCS)) 2468 | { 2469 | // Wait Until Ready 2470 | while ( (ejtag_read_h(FLASH_MEMORY_START) & STATUS_READY) != STATUS_READY ); 2471 | } 2472 | else 2473 | { 2474 | // Wait Until Ready 2475 | while ( (ejtag_read_h(addr) & STATUS_READY) != (data & STATUS_READY) ); 2476 | } 2477 | 2478 | } 2479 | 2480 | 2481 | void sflash_erase_area(unsigned int start, unsigned int length) 2482 | { 2483 | int cur_block; 2484 | int tot_blocks; 2485 | unsigned int reg_start; 2486 | unsigned int reg_end; 2487 | 2488 | reg_start = start; 2489 | reg_end = reg_start + length; 2490 | 2491 | tot_blocks = 0; 2492 | 2493 | for (cur_block = 1; cur_block <= block_total; cur_block++) 2494 | { 2495 | block_addr = blocks[cur_block]; 2496 | if ((block_addr >= reg_start) && (block_addr < reg_end)) tot_blocks++; 2497 | } 2498 | 2499 | printf("Total Blocks to Erase: %d\n\n", tot_blocks); 2500 | 2501 | for (cur_block = 1; cur_block <= block_total; cur_block++) 2502 | { 2503 | block_addr = blocks[cur_block]; 2504 | 2505 | if ((block_addr >= reg_start) && (block_addr < reg_end)) 2506 | { 2507 | 2508 | printf("Erasing block: %d (addr = %08x)...", cur_block, block_addr); 2509 | fflush(stdout); 2510 | sflash_erase_block(block_addr); 2511 | printf("Done\n"); 2512 | fflush(stdout); 2513 | } 2514 | } 2515 | 2516 | } 2517 | 2518 | 2519 | void sflash_erase_block(unsigned int addr) 2520 | { 2521 | if (cmd_type == CMD_TYPE_SPI) 2522 | { 2523 | spiflash_erase_block(addr); 2524 | } 2525 | 2526 | if (cmd_type == CMD_TYPE_AMD) 2527 | { 2528 | 2529 | //Unlock Block 2530 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA); 2531 | ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055); 2532 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00800080); 2533 | 2534 | //Erase Block 2535 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA); 2536 | ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055); 2537 | ejtag_write_h(addr, 0x00300030); 2538 | 2539 | 2540 | // Wait for Erase Completion 2541 | sflash_poll(addr, 0xFFFF); 2542 | 2543 | } 2544 | 2545 | if (cmd_type == CMD_TYPE_SST) 2546 | { 2547 | 2548 | //Unlock Block 2549 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA); 2550 | ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055); 2551 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00800080); 2552 | 2553 | //Erase Block 2554 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA); 2555 | ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055); 2556 | ejtag_write_h(addr, 0x00500050); 2557 | 2558 | // Wait for Erase Completion 2559 | sflash_poll(addr, 0xFFFF); 2560 | 2561 | } 2562 | 2563 | if ((cmd_type == CMD_TYPE_BSC) || (cmd_type == CMD_TYPE_SCS)) 2564 | { 2565 | 2566 | //Unlock Block 2567 | ejtag_write_h(addr, 0x00500050); // Clear Status Command 2568 | ejtag_write_h(addr, 0x00600060); // Unlock Flash Block Command 2569 | ejtag_write_h(addr, 0x00D000D0); // Confirm Command 2570 | ejtag_write_h(addr, 0x00700070); 2571 | 2572 | 2573 | // Wait for Unlock Completion 2574 | sflash_poll(addr, STATUS_READY); 2575 | 2576 | //Erase Block 2577 | ejtag_write_h(addr, 0x00500050); // Clear Status Command 2578 | ejtag_write_h(addr, 0x00200020); // Block Erase Command 2579 | ejtag_write_h(addr, 0x00D000D0); // Confirm Command 2580 | ejtag_write_h(addr, 0x00700070); 2581 | 2582 | // Wait for Erase Completion 2583 | sflash_poll(addr, STATUS_READY); 2584 | 2585 | } 2586 | 2587 | sflash_reset(); 2588 | 2589 | } 2590 | 2591 | void chip_erase(void) 2592 | { 2593 | 2594 | printf("Chip Erase\n"); 2595 | 2596 | // FLASH_MEMORY_START = (0x1fc0000); 2597 | //Unlock Block 2598 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA); 2599 | ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055); 2600 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00800080); 2601 | 2602 | //Erase Block 2603 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA); 2604 | ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055); 2605 | 2606 | ejtag_write_h(0x1fc00000, 0x00100010); 2607 | 2608 | } 2609 | 2610 | void sflash_reset(void) 2611 | { 2612 | 2613 | if ((cmd_type == CMD_TYPE_AMD) || (cmd_type == CMD_TYPE_SST)) 2614 | { 2615 | 2616 | ejtag_write_h(FLASH_MEMORY_START, 0x00F000F0); // Set array to read mode 2617 | } 2618 | 2619 | if ((cmd_type == CMD_TYPE_BSC) || (cmd_type == CMD_TYPE_SCS)) 2620 | { 2621 | ejtag_write_h(FLASH_MEMORY_START, 0x00500050); // Clear CSR 2622 | ejtag_write_h(FLASH_MEMORY_START, 0x00ff00ff); // Set array to read mode 2623 | } 2624 | 2625 | } 2626 | 2627 | void sflash_write_word(unsigned int addr, unsigned int data) 2628 | { 2629 | unsigned int data_lo, data_hi; 2630 | 2631 | 2632 | if (USE_DMA) 2633 | { 2634 | // DMA Uses Byte Lanes 2635 | data_lo = data; 2636 | data_hi = data; 2637 | 2638 | } 2639 | else 2640 | { 2641 | // PrAcc Does Not 2642 | // Speedtouch does not accept flashing with DMA, so you have to use /nodma 2643 | 2644 | data_lo = (data & 0xFFFF); 2645 | data_hi = ((data >> 16) & 0xFFFF); 2646 | 2647 | } 2648 | 2649 | if (cmd_type == CMD_TYPE_SPI) 2650 | { 2651 | spiflash_write_word(addr, data); 2652 | } 2653 | 2654 | if (cmd_type == CMD_TYPE_AMD) 2655 | { 2656 | 2657 | if (bypass) 2658 | { 2659 | if (proc_id == 0x00000001) 2660 | { 2661 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0); 2662 | ejtag_write_h(addr+2, data_lo); 2663 | tnano(100); 2664 | 2665 | 2666 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0); 2667 | ejtag_write_h(addr, data_hi); 2668 | tnano(100); 2669 | } 2670 | else 2671 | { 2672 | 2673 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0); 2674 | ejtag_write_h(addr, data_lo); 2675 | 2676 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0); 2677 | ejtag_write_h(addr+2, data_hi); 2678 | 2679 | } 2680 | } 2681 | else 2682 | 2683 | if (speedtouch || proc_id == 0x00000001) 2684 | { 2685 | // Speedtouch uses a different flash address pattern. 2686 | // Handle Half Of Word 2687 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA); 2688 | ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055); 2689 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0); 2690 | ejtag_write_h(addr+2, data_lo); 2691 | 2692 | // Wait for Completion 2693 | sflash_poll(addr, (data & 0xffff)); 2694 | 2695 | // Now Handle Other Half Of Word 2696 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA); 2697 | ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055); 2698 | ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0); 2699 | ejtag_write_h(addr, data_hi); 2700 | 2701 | // Wait for Completion 2702 | sflash_poll(addr+2, ((data >> 16) & 0xffff)); 2703 | } 2704 | 2705 | else 2706 | { 2707 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA); 2708 | ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055); 2709 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00A000A0); 2710 | ejtag_write_h(addr, data_lo); 2711 | 2712 | // Wait for Completion 2713 | sflash_poll(addr, (data & 0xffff)); 2714 | 2715 | // Now Handle Other Half Of Word 2716 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA); 2717 | ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055); 2718 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00A000A0); 2719 | ejtag_write_h(addr+2, data_hi); 2720 | 2721 | // Wait for Completion 2722 | sflash_poll(addr+2, ((data >> 16) & 0xffff)); 2723 | } 2724 | 2725 | 2726 | } 2727 | 2728 | if (cmd_type == CMD_TYPE_SST) 2729 | { 2730 | // Handle Half Of Word 2731 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA); 2732 | ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055); 2733 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00A000A0); 2734 | ejtag_write_h(addr, data_lo); 2735 | 2736 | // Wait for Completion 2737 | sflash_poll(addr, (data & 0xffff)); 2738 | 2739 | // Now Handle Other Half Of Word 2740 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA); 2741 | ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055); 2742 | ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00A000A0); 2743 | ejtag_write_h(addr+2, data_hi); 2744 | 2745 | // Wait for Completion 2746 | sflash_poll(addr+2, ((data >> 16) & 0xffff)); 2747 | } 2748 | 2749 | if ((cmd_type == CMD_TYPE_BSC) || (cmd_type == CMD_TYPE_SCS)) 2750 | { 2751 | 2752 | 2753 | // Handle Half Of Word 2754 | ejtag_write_h(addr, 0x00500050); // Clear Status Command 2755 | ejtag_write_h(addr, 0x00400040); // Write Command 2756 | ejtag_write_h(addr, data_lo); // Send HalfWord Data 2757 | // ejtag_write_h(addr, 0x00700070); // Check Status Command 2758 | 2759 | // Wait for Completion 2760 | sflash_poll(addr, STATUS_READY); 2761 | 2762 | // Now Handle Other Half Of Word 2763 | ejtag_write_h(addr+2, 0x00500050); // Clear Status Command 2764 | ejtag_write_h(addr+2, 0x00400040); // Write Command 2765 | ejtag_write_h(addr+2, data_hi); // Send HalfWord Data 2766 | // ejtag_write_h(addr+2, 0x00700070); // Check Status Command 2767 | 2768 | 2769 | sflash_poll(addr, STATUS_READY); 2770 | } 2771 | } 2772 | 2773 | 2774 | 2775 | 2776 | 2777 | void show_usage(void) 2778 | { 2779 | 2780 | flash_chip_type* flash_chip = flash_chip_list; 2781 | processor_chip_type* processor_chip = processor_chip_list; 2782 | int counter = 0; 2783 | 2784 | printf( " ABOUT: This program reads/writes flash memory on the WRT54G/GS and\n" 2785 | " compatible routers via EJTAG using either DMA Access routines\n" 2786 | " or PrAcc routines (slower/more compatible). Processor chips\n" 2787 | " supported in this version include the following chips:\n\n" 2788 | " Supported Chips\n" 2789 | " ---------------\n"); 2790 | 2791 | while (processor_chip->chip_id) 2792 | { 2793 | printf(" %-40.40s\n", processor_chip->chip_descr); 2794 | processor_chip++; 2795 | } 2796 | 2797 | printf( "\n\n"); 2798 | printf( " USAGE: tjtag [parameter] \n" 2799 | " \n" 2800 | " \n" 2801 | " /bypass /st5\n\n" 2802 | 2803 | " Required Parameter\n" 2804 | " ------------------\n" 2805 | " -backup:cfe\n" 2806 | " -backup:nvram\n" 2807 | " -backup:kernel\n" 2808 | " -backup:wholeflash\n" 2809 | " -backup:custom\n" 2810 | " -backup:bsp\n" 2811 | " -erase:cfe\n" 2812 | " -erase:nvram\n" 2813 | " -erase:kernel\n" 2814 | " -erase:wholeflash\n" 2815 | " -erase:custom\n" 2816 | " -erase:bsp\n" 2817 | " -flash:cfe\n" 2818 | " -flash:nvram\n" 2819 | " -flash:kernel\n" 2820 | " -flash:wholeflash\n" 2821 | " -flash:custom\n" 2822 | " -flash:bsp\n" 2823 | " -probeonly\n" 2824 | " -probeonly:custom\n" 2825 | " and for Ti AR7 \n" 2826 | " -backup:mtd2\n" 2827 | " -backup:mtd3\n" 2828 | " -backup:mtd4\n" 2829 | " -backup:full\n" 2830 | " -erase:mtd2\n" 2831 | " -erase:mtd3\n" 2832 | " -erase:mtd4\n" 2833 | " -erase:full\n" 2834 | " -flash:mtd2\n" 2835 | " -flash:mtd3\n" 2836 | " -flash:mtd4\n" 2837 | " -flash:full\n\n" 2838 | 2839 | " Optional with -backup:, -erase:, -flash: wgrv8bdata, wgrv9bdata, cfe128\n\n" 2840 | 2841 | " Optional Switches\n" 2842 | " -----------------\n" 2843 | " /noreset ........... prevent Issuing EJTAG CPU reset\n" 2844 | " /noemw ............. prevent Enabling Memory Writes\n" 2845 | " /nocwd ............. prevent Clearing CPU Watchdog Timer\n" 2846 | " /nobreak ........... prevent Issuing Debug Mode JTAGBRK\n" 2847 | " /noerase ........... prevent Forced Erase before Flashing\n" 2848 | " /notimestamp ....... prevent Timestamping of Backups\n" 2849 | " /dma ............... force use of DMA routines\n" 2850 | " /nodma ............. force use of PRACC routines (No DMA)\n" 2851 | " /window:XXXXXXXX ... custom flash window base (in HEX)\n" 2852 | " /start:XXXXXXXX .... custom start location (in HEX)\n" 2853 | " /length:XXXXXXXX ... custom length (in HEX)\n" 2854 | " /silent ............ prevent scrolling display of data\n" 2855 | " /skipdetect ........ skip auto detection of CPU Chip ID\n" 2856 | " /instrlen:XX ....... set instruction length manually\n" 2857 | " /wiggler ........... use wiggler cable\n" 2858 | " /bypass ............ Unlock Bypass command & disable polling\n" 2859 | " /delay:XXXXXX ...... add delay to communication\n" 2860 | " /st5 ............... Use Speedtouch ST5xx flash routines instead of WRT routines\n" 2861 | " /reboot............. sets the process and reboots\n" 2862 | " /swap_endian........ swap endianess during backup - most Atheros based routers\n" 2863 | " /flash_debug........ flash chip debug messages, show flash MFG and Device ID\n\n" 2864 | 2865 | " /fc:XX = Optional (Manual) Flash Chip Selection\n" 2866 | " -----------------------------------------------\n"); 2867 | 2868 | while (flash_chip->vendid) 2869 | { 2870 | printf(" /fc:%02d ............. %-40.40s\n", ++counter, flash_chip->flash_part); 2871 | flash_chip++; 2872 | } 2873 | 2874 | printf( "\n\n"); 2875 | printf( " NOTES: 1) If 'flashing' - the source filename must exist as follows:\n" 2876 | " CFE.BIN, NVRAM.BIN, KERNEL.BIN, WHOLEFLASH.BIN or CUSTOM.BIN\n" 2877 | " BSP.BIN\n\n" 2878 | "...........or for Ti AR7 MTD2.BIN, MTD3.BIN\n\n" 2879 | 2880 | " 2) If you have difficulty auto-detecting a particular flash part\n" 2881 | " you can manually specify your exact part using the /fc:XX option.\n\n" 2882 | 2883 | " 3) If you have difficulty with the older bcm47xx chips or when no CFE\n" 2884 | " is currently active/operational you may want to try both the\n" 2885 | " /noreset and /nobreak command line options together. Some bcm47xx\n" 2886 | " chips *may* always require both these options to function properly.\n\n" 2887 | 2888 | " 4) When using this utility, usually it is best to type the command line\n" 2889 | " out, then plug in the router, and then hit quickly to avoid\n" 2890 | " the CPUs watchdog interfering with the EJTAG operations.\n\n" 2891 | 2892 | " 5) /bypass - enables Unlock bypass command for some AMD/Spansion type\n" 2893 | " flashes, it also disables polling\n\n" 2894 | 2895 | " ***************************************************************************\n" 2896 | " * Flashing the KERNEL or WHOLEFLASH will take a very long time using JTAG *\n" 2897 | " * via this utility. You are better off flashing the CFE & NVRAM files *\n" 2898 | " * & then using the normal TFTP method to flash the KERNEL via ethernet. *\n" 2899 | " ***************************************************************************\n\n"); 2900 | } 2901 | 2902 | 2903 | int main(int argc, char** argv) 2904 | { 2905 | char choice[128]; 2906 | int run_option; 2907 | int j; 2908 | 2909 | printf("\n"); 2910 | printf("==============================================\n"); 2911 | printf(" EJTAG Debrick Utility v3.0.1 Tornado-MOD \n"); 2912 | printf("==============================================\n\n"); 2913 | 2914 | 2915 | 2916 | if (argc < 2) 2917 | { 2918 | show_usage(); 2919 | exit(1); 2920 | } 2921 | 2922 | strcpy(choice,argv[1]); 2923 | 2924 | run_option = 0; 2925 | 2926 | if (strcasecmp(choice,"-backup:cfe")==0) 2927 | { 2928 | run_option = 1; 2929 | strcpy(AREA_NAME, "CFE"); 2930 | } 2931 | if (strcasecmp(choice,"-backup:cf1")==0) 2932 | { 2933 | run_option = 1; 2934 | strcpy(AREA_NAME, "CF1"); 2935 | } 2936 | if (strcasecmp(choice,"-backup:cfe128")==0) 2937 | { 2938 | run_option = 1; 2939 | strcpy(AREA_NAME, "CFE128"); 2940 | } 2941 | 2942 | if (strcasecmp(choice,"-backup:nvram")==0) 2943 | { 2944 | run_option = 1; 2945 | strcpy(AREA_NAME, "NVRAM"); 2946 | } 2947 | if (strcasecmp(choice,"-backup:kernel")==0) 2948 | { 2949 | run_option = 1; 2950 | strcpy(AREA_NAME, "KERNEL"); 2951 | } 2952 | if (strcasecmp(choice,"-backup:wholeflash")==0) 2953 | { 2954 | run_option = 1; 2955 | strcpy(AREA_NAME, "WHOLEFLASH"); 2956 | } 2957 | if (strcasecmp(choice,"-backup:custom")==0) 2958 | { 2959 | run_option = 1; 2960 | strcpy(AREA_NAME, "CUSTOM"); 2961 | custom_options++; 2962 | } 2963 | if (strcasecmp(choice,"-backup:bsp")==0) 2964 | { 2965 | run_option = 1; 2966 | strcpy(AREA_NAME, "BSP"); 2967 | } 2968 | if (strcasecmp(choice,"-backup:red")==0) 2969 | { 2970 | run_option = 1; 2971 | strcpy(AREA_NAME, "RED"); 2972 | } 2973 | if (strcasecmp(choice,"-backup:wgrv8bdata")==0) 2974 | { 2975 | run_option = 1; 2976 | strcpy(AREA_NAME, "WGRV8BDATA"); 2977 | } 2978 | if (strcasecmp(choice,"-backup:wgrv9bdata")==0) 2979 | { 2980 | run_option = 1; 2981 | strcpy(AREA_NAME, "WGRV9BDATA"); 2982 | } 2983 | if (strcasecmp(choice,"-erase:cfe")==0) 2984 | { 2985 | run_option = 2; 2986 | strcpy(AREA_NAME, "CFE"); 2987 | } 2988 | if (strcasecmp(choice,"-erase:wgrv9bdata")==0) 2989 | { 2990 | run_option = 2; 2991 | strcpy(AREA_NAME, "WGRV9BDATA"); 2992 | } 2993 | if (strcasecmp(choice,"-erase:wgrv9nvram")==0) 2994 | { 2995 | run_option = 2; 2996 | strcpy(AREA_NAME, "WGRV9NVRAM"); 2997 | } 2998 | if (strcasecmp(choice,"-erase:wgrv8bdata")==0) 2999 | { 3000 | run_option = 2; 3001 | strcpy(AREA_NAME, "WGRV8BDATA"); 3002 | } 3003 | if (strcasecmp(choice,"-erase:cf1")==0) 3004 | { 3005 | run_option = 2; 3006 | strcpy(AREA_NAME, "CF1"); 3007 | } 3008 | if (strcasecmp(choice,"-erase:cfe128")==0) 3009 | { 3010 | run_option = 2; 3011 | strcpy(AREA_NAME, "CFE128"); 3012 | } 3013 | if (strcasecmp(choice,"-erase:nvram")==0) 3014 | { 3015 | run_option = 2; 3016 | strcpy(AREA_NAME, "NVRAM"); 3017 | } 3018 | if (strcasecmp(choice,"-erase:kernel")==0) 3019 | { 3020 | run_option = 2; 3021 | strcpy(AREA_NAME, "KERNEL"); 3022 | } 3023 | if (strcasecmp(choice,"-erase:wholeflash")==0) 3024 | { 3025 | run_option = 2; 3026 | strcpy(AREA_NAME, "WHOLEFLASH"); 3027 | } 3028 | if (strcasecmp(choice,"-erase:custom")==0) 3029 | { 3030 | run_option = 2; 3031 | strcpy(AREA_NAME, "CUSTOM"); 3032 | custom_options++; 3033 | } 3034 | if (strcasecmp(choice,"-erase:bsp")==0) 3035 | { 3036 | run_option = 2; 3037 | strcpy(AREA_NAME, "BSP"); 3038 | } 3039 | if (strcasecmp(choice,"-spi_chiperase")==0) 3040 | { 3041 | run_option = 6; 3042 | 3043 | } 3044 | if (strcasecmp(choice,"-erase:red")==0) 3045 | { 3046 | run_option = 2; 3047 | strcpy(AREA_NAME, "RED"); 3048 | } 3049 | if (strcasecmp(choice,"-flash:cfe")==0) 3050 | { 3051 | run_option = 3; 3052 | strcpy(AREA_NAME, "CFE"); 3053 | } 3054 | if (strcasecmp(choice,"-flash:cf1")==0) 3055 | { 3056 | run_option = 3; 3057 | strcpy(AREA_NAME, "CF1"); 3058 | } 3059 | if (strcasecmp(choice,"-flash:cfe128")==0) 3060 | { 3061 | run_option = 3; 3062 | strcpy(AREA_NAME, "CFE128"); 3063 | } 3064 | if (strcasecmp(choice,"-flash:nvram")==0) 3065 | { 3066 | run_option = 3; 3067 | strcpy(AREA_NAME, "NVRAM"); 3068 | } 3069 | if (strcasecmp(choice,"-flash:wgrv8bdata")==0) 3070 | { 3071 | run_option = 3; 3072 | strcpy(AREA_NAME, "WGRV8BDATA"); 3073 | } 3074 | if (strcasecmp(choice,"-flash:wgrv9bdata")==0) 3075 | { 3076 | run_option = 3; 3077 | strcpy(AREA_NAME, "WGRV9BDATA"); 3078 | } 3079 | if (strcasecmp(choice,"-flash:kernel")==0) 3080 | { 3081 | run_option = 3; 3082 | strcpy(AREA_NAME, "KERNEL"); 3083 | } 3084 | if (strcasecmp(choice,"-flash:wholeflash")==0) 3085 | { 3086 | run_option = 3; 3087 | strcpy(AREA_NAME, "WHOLEFLASH"); 3088 | } 3089 | if (strcasecmp(choice,"-flash:custom")==0) 3090 | { 3091 | run_option = 3; 3092 | strcpy(AREA_NAME, "CUSTOM"); 3093 | custom_options++; 3094 | } 3095 | if (strcasecmp(choice,"-flash:bsp")==0) 3096 | { 3097 | run_option = 3; 3098 | strcpy(AREA_NAME, "BSP"); 3099 | } 3100 | 3101 | if (strcasecmp(choice,"-flash:red")==0) 3102 | { 3103 | run_option = 3; 3104 | strcpy(AREA_NAME, "RED"); 3105 | } 3106 | if (strcasecmp(choice,"-probeonly")==0) 3107 | { 3108 | run_option = 4; 3109 | } 3110 | if (strcasecmp(choice,"-probeonly:custom")==0) 3111 | { 3112 | run_option = 4; 3113 | strcpy(AREA_NAME, "CUSTOM"); 3114 | } 3115 | 3116 | if (strncasecmp(choice,"-load:", 5)==0) 3117 | { 3118 | run_option = 5; 3119 | strcpy(AREA_NAME, &choice[6]); 3120 | } 3121 | 3122 | /* Extras for AR7 */ 3123 | if (strcasecmp(choice,"-backup:mtd2")==0) { run_option = 1; strcpy(AREA_NAME, "MTD2"); } 3124 | if (strcasecmp(choice,"-backup:mtd3")==0) { run_option = 1; strcpy(AREA_NAME, "MTD3"); } 3125 | if (strcasecmp(choice,"-backup:mtd4")==0) { run_option = 1; strcpy(AREA_NAME, "MTD4"); } 3126 | if (strcasecmp(choice,"-backup:full")==0) { run_option = 1; strcpy(AREA_NAME, "FULL"); } 3127 | if (strcasecmp(choice,"-erase:mtd2")==0) { run_option = 2; strcpy(AREA_NAME, "MTD2"); } 3128 | if (strcasecmp(choice,"-erase:mtd3")==0) { run_option = 2; strcpy(AREA_NAME, "MTD3"); } 3129 | if (strcasecmp(choice,"-erase:mtd4")==0) { run_option = 2; strcpy(AREA_NAME, "MTD4"); } 3130 | if (strcasecmp(choice,"-erase:full")==0) { run_option = 2; strcpy(AREA_NAME, "FULL"); } 3131 | if (strcasecmp(choice,"-flash:mtd2")==0) { run_option = 3; strcpy(AREA_NAME, "MTD2"); } 3132 | if (strcasecmp(choice,"-flash:mtd3")==0) { run_option = 3; strcpy(AREA_NAME, "MTD3"); } 3133 | if (strcasecmp(choice,"-flash:mtd4")==0) { run_option = 3; strcpy(AREA_NAME, "MTD4"); } 3134 | if (strcasecmp(choice,"-flash:full")==0) { run_option = 3; strcpy(AREA_NAME, "FULL"); } 3135 | /* end AR7 */ 3136 | 3137 | if (run_option == 0) 3138 | { 3139 | show_usage(); 3140 | printf("\n*** ERROR - Invalid [option] specified ***\n\n"); 3141 | exit(1); 3142 | } 3143 | 3144 | if (argc > 2) 3145 | { 3146 | j = 2; 3147 | while (j < argc) 3148 | { 3149 | strcpy(choice,argv[j]); 3150 | 3151 | if (strcasecmp(choice,"/noreset")==0) issue_reset = 0; 3152 | else if (strcasecmp(choice,"/noemw")==0) issue_enable_mw = 0; 3153 | else if (strcasecmp(choice,"/nocwd")==0) issue_watchdog = 0; 3154 | else if (strcasecmp(choice,"/nobreak")==0) issue_break = 0; 3155 | else if (strcasecmp(choice,"/noerase")==0) issue_erase = 0; 3156 | else if (strcasecmp(choice,"/notimestamp")==0) issue_timestamp = 0; 3157 | else if (strcasecmp(choice,"/dma")==0) force_dma = 1; 3158 | else if (strcasecmp(choice,"/nodma")==0) force_nodma = 1; 3159 | else if (strncasecmp(choice,"/fc:",4)==0) selected_fc = strtoul(((char *)choice + 4),NULL,10); 3160 | else if (strcasecmp(choice,"/bypass")==0) bypass = 1; 3161 | else if (strcasecmp(choice, "/reboot")==0) issue_reboot = 1; 3162 | else if (strncasecmp(choice,"/window:",8)==0) 3163 | { 3164 | selected_window = strtoul(((char *)choice + 8),NULL,16); 3165 | custom_options++; 3166 | probe_options++; 3167 | } 3168 | else if (strncasecmp(choice,"/start:",7)==0) 3169 | { 3170 | selected_start = strtoul(((char *)choice + 7),NULL,16); 3171 | custom_options++; 3172 | } 3173 | else if (strncasecmp(choice,"/length:",8)==0) 3174 | { 3175 | selected_length = strtoul(((char *)choice + 8),NULL,16); 3176 | custom_options++; 3177 | } 3178 | else if (strcasecmp(choice,"/silent")==0) silent_mode = 1; 3179 | else if (strcasecmp(choice,"/skipdetect")==0) skipdetect = 1; 3180 | else if (strncasecmp(choice,"/instrlen:",10)==0) instrlen = strtoul(((char *)choice + 10),NULL,10); 3181 | else if (strcasecmp(choice,"/wiggler")==0) wiggler = 1; 3182 | else if (strcasecmp(choice,"/st5")==0) speedtouch = 1; 3183 | else if (strcasecmp(choice,"/flash_debug")==0) Flash_DEBUG = 1; 3184 | else if (strncasecmp(choice,"/delay:",7)==0) delay = strtoul(((char *)choice + 7),NULL,10); 3185 | else if (strcasecmp(choice,"/xbit")==0) xbit = 1; 3186 | else if (strcasecmp(choice,"/swap_endian")==0) swap_endian = 1; 3187 | else 3188 | { 3189 | show_usage(); 3190 | printf("\n*** ERROR - Invalid