1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Flash "self-write" module File: dev_flashop_engine.S 5 * 6 * This module takes care of the case of writing to the flash 7 * memory that CFE is currently reading its code from. 8 * 9 * Note: this code is written to be position-independent, even 10 * for non-PIC versions of CFE! It will be copied (with memcpy) 11 * into the heap for execution. 12 * 13 * Author: Mitch Lichtenberg (mpl@broadcom.com) 14 * 15 ********************************************************************* 16 * 17 * Copyright 2000,2001,2002,2003 18 * Broadcom Corporation. All rights reserved. 19 * 20 * This software is furnished under license and may be used and 21 * copied only in accordance with the following terms and 22 * conditions. Subject to these conditions, you may download, 23 * copy, install, use, modify and distribute modified or unmodified 24 * copies of this software in source and/or binary form. No title 25 * or ownership is transferred hereby. 26 * 27 * 1) Any source code used, modified or distributed must reproduce 28 * and retain this copyright notice and list of conditions 29 * as they appear in the source file. 30 * 31 * 2) No right is granted to use any trade name, trademark, or 32 * logo of Broadcom Corporation. The "Broadcom Corporation" 33 * name may not be used to endorse or promote products derived 34 * from this software without the prior written permission of 35 * Broadcom Corporation. 36 * 37 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 38 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 39 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 40 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 41 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 42 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 45 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 46 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 47 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 48 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 49 * THE POSSIBILITY OF SUCH DAMAGE. 50 ********************************************************************* */ 51 52#include "sbmips.h" 53#include "mipsmacros.h" 54 55#include "bsp_config.h" 56#include "dev_newflash.h" 57 58/* ********************************************************************* 59 * Macros 60 ********************************************************************* */ 61 62#if defined(__MIPSEB) && defined(_MIPSEB_DATA_INVARIANT_) 63 64#define FLASHCMD_8(base,offset,value) \ 65 li t0,value ; \ 66 ADD base,((offset)<<1) ; \ 67 xori base,3 ; \ 68 sb t0,0(base) ; \ 69 xori base,3 ; \ 70 SUB base,((offset)<<1) 71 72#define FLASHCMD_16(base,offset,value) \ 73 li t0,value ; \ 74 ADD base,((offset)<<1) ; \ 75 xori base,2 ; \ 76 sh t0,0(base) ; \ 77 xori base,2 ; \ 78 SUB base,((offset)<<1) 79 80#define FLASHCMD_16B(base,offset,value) \ 81 li t0,value ; \ 82 ADD base,((offset)<<1) ; \ 83 xori base,3 ; \ 84 sb t0,0(base) ; \ 85 xori base,3 ; \ 86 SUB base,((offset)<<1) 87 88#else 89 90#define FLASHCMD_8(base,offset,value) \ 91 li t0,value ; \ 92 sb t0,offset(base) 93 94#define FLASHCMD_16(base,offset,value) \ 95 li t0,value ; \ 96 sh t0,((offset)<<1)(base) 97 98#define FLASHCMD_16B(base,offset,value) \ 99 li t0,value ; \ 100 sb t0,((offset)<<1)(base) 101 102#endif 103 104/* ********************************************************************* 105 * flashop_engine 106 * 107 * This routine is written in a PIC method to allow us to do 108 * flash operations without any help from CFE. We need to do 109 * this when we're not relocated and want to muck with the 110 * flash we're running from. 111 * 112 * This routine follows some simple instructions in a table, 113 * so you can batch up the operations in one place. 114 * 115 * Input parameters: 116 * a0 - pointer to instruction list 117 * 118 * Return value: 119 * v0 - 0 if all instructions succeeded 120 * else less than zero, # of failing instructions 121 ********************************************************************* */ 122 123 .text 124 125#define reg_op t3 126#define reg_base t4 127#define reg_dest t5 128#define reg_src t6 129#define reg_cnt t7 130 131LEAF(flashop_engine) 132 133instloop: LR reg_op,FEINST_OP(a0) /* Load instruction */ 134 LR reg_base,FEINST_BASE(a0) 135 LR reg_dest,FEINST_DEST(a0) 136 LR reg_src,FEINST_SRC(a0) 137 LR reg_cnt,FEINST_CNT(a0) 138 li v0,0 /* total of result values */ 139 li v1,0 /* result for this function */ 140 141#ifdef __long64 142 dli t0,0x9000000000000000 /* uncached - XKPHYS */ 143 or reg_base,t0 /* so we can access flash beyond KSEG */ 144#else 145 or reg_base,K1BASE /* 32-bit, regular KSEG */ 146#endif 147 148/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 149 bne reg_op,FEOP_RETURN,99f /* Return to main prog */ 150 151 j ra 152/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 15399: bne reg_op,FEOP_REBOOT,99f /* restart system */ 154 155 li t0,0xBFC00000 /* jump to boot vector */ 156 j t0 157/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 15899: bne reg_op,FEOP_READ8,99f /* Read, 8-bit mode */ 159 160 ADD reg_src,reg_src,reg_base 161 1621: lbu t0,0(reg_src) /* Copy user data */ 163 sb t0,0(reg_dest) 164 ADD reg_src,1 165 add reg_dest,1 166 sub reg_cnt,1 167 bgt reg_cnt,zero,1b 168 169 b nextinst 170/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 17199: bne reg_op,FEOP_READ16,99f /* Read, 16-bit mode */ 172 173 ADD reg_src,reg_src,reg_base 174 175 li t0,1 /* test bottom bit */ 176 and t0,t0,reg_src /* t0 == 1 if odd */ 177 beq t0,zero,1f /* no odd byte to worry about */ 178 179 SUB reg_src,reg_src,t0 /* make even value */ 180 lh t0,0(reg_src) /* interesting byte is odd */ 181#ifdef __MIPSEB 182 sb t0,0(reg_dest) /* interesting byte in low 8 bits */ 183#else 184 srl t0,t0,8 /* little endian */ 185 sb t0,0(reg_dest) /* interesting byte is high 8 bits */ 186#endif 187 188 ADD reg_src,2 /* advance one word (we made addr even above) */ 189 add reg_dest,1 /* dest always written by bytes */ 190 sub reg_cnt,1 191 1921: beq reg_cnt,zero,nextinst 193 194 lh t0,0(reg_src) /* Copy user data */ 195 196#ifdef __MIPSEB 197 sb t0,1(reg_dest) /* Big endian to memory */ 198 srl t0,t0,8 /* t0 = 0x1234 -> 0x12 0x34 */ 199 sb t0,0(reg_dest) 200#else 201 sb t0,0(reg_dest) /* little endian */ 202 srl t0,t0,8 /* t0 = 0x1234 -> 0x34 0x12 */ 203 sb t0,1(reg_dest) 204#endif 205 206 ADD reg_src,2 207 add reg_dest,2 208 sub reg_cnt,2 209 bgt reg_cnt,1,1b 210 211 beq reg_cnt,zero,nextinst /* no straggler */ 212 213 lh t0,0(reg_src) /* interesting byte is odd */ 214#ifdef __MIPSEB 215 srl t0,t0,8 /* little endian */ 216 sb t0,0(reg_dest) /* interesting byte in high 8 bits */ 217#else 218 sb t0,0(reg_dest) /* interesting byte is low 8 bits */ 219#endif 220 221 b nextinst 222/* CFI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 223#if (FLASH_DRIVERS & FLASH_DRIVER_CFI) 22499: bne reg_op,FEOP_CFIQUERY8,99f /* CFI Query 8-bit */ 225 226 ADD reg_src,reg_src,reg_base 227 228 FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE) 229 2301: lbu t0,0(reg_src) /* Copy CFI data */ 231 sb t0,0(reg_dest) 232 ADD reg_src,1 233 add reg_dest,1 234 sub reg_cnt,1 235 bgt reg_cnt,zero,1b 236 237 FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT) 238 239 b nextinst 240/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 24199: bne reg_op,FEOP_CFIQUERY16,99f /* CFI Query 16-bit in word mode */ 242 243 ADD reg_src,reg_src,reg_base 244 245 FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE) 246 2471: lh t0,0(reg_src) /* Copy CFI data */ 248 sb t0,0(reg_dest) 249 ADD reg_src,2 250 add reg_dest,2 251 sub reg_cnt,2 252 bgt reg_cnt,zero,1b 253 254 FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT) 255 256 b nextinst 257/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 25899: bne reg_op,FEOP_CFIQUERY16B,99f /* CFI Query 16-bit in byte mode */ 259 260 ADD reg_src,reg_src,reg_base 261 262 FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE) 263 2641: lb t0,0(reg_src) /* Copy CFI data */ 265 sb t0,0(reg_dest) 266 ADD reg_src,1 267 add reg_dest,1 268 sub reg_cnt,1 269 bgt reg_cnt,zero,1b 270 271 FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT) 272 273 b nextinst 274#endif 275 276/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 27799: bne reg_op,FEOP_MEMCPY,99f /* Generic memcpy */ 278 2791: lbu t0,0(reg_src) 280 sb t0,0(reg_dest) 281 add reg_src,1 282 add reg_dest,1 283 sub reg_cnt,1 284 bgt reg_cnt,zero,1b 285 286 b nextinst 287 288 289/* AMD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 290#if (FLASH_DRIVERS & FLASH_DRIVER_AMD) 29199: bne reg_op,FEOP_AMD_ERASE8,99f /* AMD erase (8-bit) */ 292 293 ADD reg_dest,reg_dest,reg_base 294 295 /* Do an "unlock write" sequence (cycles 1-2) */ 296 297 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 298 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 299 300 /* send the erase command (cycle 3) */ 301 302 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3) 303 304 /* Do an "unlock write" sequence (cycles 4-5) */ 305 306 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 307 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 308 309 /* Send the "erase sector" qualifier (cycle 6) */ 310 311 FLASHCMD_8(reg_dest,0,AMD_FLASH_ERASE_SEC_6) 312 313 /* Wait for the erase to complete */ 314 3151: lb t0,0(reg_dest) # get byte 316 and t0,0xFF # test hi byte 317 bne t0,0xFF,1b # go till bit is set 318 319 b nextinst 320/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 32199: bne reg_op,FEOP_AMD_ERASE16,99f /* AMD erase (16-bit in word mode) */ 322 323 ADD reg_dest,reg_dest,reg_base 324 325 /* Do an "unlock write" sequence (cycles 1-2) */ 326 327 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 328 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 329 330 /* send the erase command (cycle 3) */ 331 332 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3) 333 334 /* Do an "unlock write" sequence (cycles 4-5) */ 335 336 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 337 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 338 339 /* Send the "erase sector" qualifier (cycle 6) */ 340 341 FLASHCMD_16(reg_dest,0,AMD_FLASH_ERASE_SEC_6) 342 343 /* Wait for the erase to complete */ 344 3451: lh t0,0(reg_dest) # get word 346 and t0,0xFF # test byte 347 bne t0,0xFF,1b # go till erased 348 349 b nextinst 350 351/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 35299: bne reg_op,FEOP_AMD_ERASE16B,99f /* AMD erase (16-bit in byte mode) */ 353 354 ADD reg_dest,reg_dest,reg_base 355 356 /* Do an "unlock write" sequence (cycles 1-2) */ 357 358 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 359 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 360 361 /* send the erase command (cycle 3) */ 362 363 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3) 364 365 /* Do an "unlock write" sequence (cycles 4-5) */ 366 367 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 368 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 369 370 /* Send the "erase sector" qualifier (cycle 6) */ 371 372 FLASHCMD_16B(reg_dest,0,AMD_FLASH_ERASE_SEC_6) 373 374 /* Wait for the erase to complete */ 375 3761: lh t0,0(reg_dest) # get word 377 and t0,0xFF # test byte 378 bne t0,0xFF,1b # go till erased 379 380 b nextinst 381/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 38299: bne reg_op,FEOP_AMD_PGM8,99f /* AMD 8-bit program */ 383 384 ADD reg_dest,reg_dest,reg_base 385 386 /* Do an "unlock write" sequence (cycles 1-2) */ 38711: 388 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 389 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 390 391 /* Send a program command (cycle 3) */ 392 393 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM) 394 395 /* Write a byte (cycle 4) */ 396 397 lbu t0,0(reg_src) 398 sb t0,0(reg_dest) # t0 = byte written to flash 399 400 /* Wait for write to complete */ 401 4021: lbu t2,0(reg_dest) # t2 = byte from flash 403 404 and t1,t2,0x80 # done if bit7 of flash 405 and t0,t0,0x80 # is same as bit7 of data 406 beq t1,t0,2f 407 408 and t1,t2,0x20 # not done if bit5 409 bne t1,0x20,1b # is still set 4102: 411 412 /* next byte... */ 413 414 add reg_src,1 # next source byte 415 ADD reg_dest,1 # next dest byte 416 sub reg_cnt,1 # one less count 417 bgt reg_cnt,0,11b 418 419 420 b nextinst 421/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 42299: bne reg_op,FEOP_AMD_PGM16,99f /* AMD 16-bit program */ 423 424 ADD reg_dest,reg_dest,reg_base 425 426 /* Do an "unlock write" sequence (cycles 1-2) */ 42711: 428 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 429 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 430 431 /* Send a program command (cycle 3) */ 432 433 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM) 434 435 /* Write a byte (cycle 4) */ 436 437 lh t0,0(reg_src) 438 sh t0,0(reg_dest) # t0 = byte written to flash 439 440 /* Wait for write to complete */ 441 4421: lh t2,0(reg_dest) # t2 = byte from flash 443 444 and t1,t2,0x80 # done if bit7 of flash 445 and t0,t0,0x80 # is same as bit7 of data 446 beq t1,t0,2f 447 448 and t1,t2,0x20 # not done if bit5 449 bne t1,0x20,1b # is still set 4502: 451 452 /* next byte... */ 453 454 add reg_src,2 # next source word 455 ADD reg_dest,2 # next dest word 456 sub reg_cnt,2 # one less count 457 bgt reg_cnt,0,11b 458 459 b nextinst 460/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 46199: bne reg_op,FEOP_AMD_PGM16B,99f /* AMD 16-bit pgm in 8-bit mode */ 462 463 ADD reg_dest,reg_dest,reg_base 464 465 /* Do an "unlock write" sequence (cycles 1-2) */ 46611: 467 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 468 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 469 470 /* Send a program command (cycle 3) */ 471 472 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM) 473 474 /* Write a byte (cycle 4) */ 475 476 lb t0,0(reg_src) 477 sb t0,0(reg_dest) # t0 = byte written to flash 478 479 /* Wait for write to complete */ 480 4811: lb t2,0(reg_dest) # t2 = byte from flash 482 483 and t1,t2,0x80 # done if bit7 of flash 484 and t0,t0,0x80 # is same as bit7 of data 485 beq t1,t0,2f 486 487 and t1,t2,0x20 # not done if bit5 488 bne t1,0x20,1b # is still set 4892: 490 491 /* next byte... */ 492 493 add reg_src,1 # next source word 494 ADD reg_dest,1 # next dest word 495 sub reg_cnt,1 # one less count 496 bgt reg_cnt,0,11b 497 498 b nextinst 499 500/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 50199: bne reg_op,FEOP_AMD_DEVCODE8,99f /* AMD 8-bit - Boot Block Location */ 502 503 ADD reg_src,reg_src,reg_base 504 505 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 506 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 507 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL) 508 509 lbu t0,AMD_FLASH_DEVCODE8(reg_src) 510 sb t0,0(reg_dest) 511 li t0,AMD_FLASH_RESET 512 sb t0,0(reg_src) 513 514 515 b nextinst 516/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 51799: bne reg_op,FEOP_AMD_DEVCODE16,99f /* AMD 8-bit - Boot Block Location */ 518 519 ADD reg_src,reg_src,reg_base 520 521 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 522 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 523 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL) 524 525 lw t0,0(reg_src) 526#ifdef __MIPSEB 527 srl t0,t0,8 /* ((3-AMD_FLASH_DEVCODE16)*8) */ 528#else 529 srl t0,t0,16 /* (AMD_FLASH_DEVCODE16*8) */ 530#endif 531 sb t0,0(reg_dest) 532 li t0,AMD_FLASH_RESET 533 sb t0,0(reg_src) 534 535 b nextinst 536/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 53799: bne reg_op,FEOP_AMD_DEVCODE16B,99f /* AMD 8-bit - Boot Block Location */ 538 539 ADD reg_src,reg_src,reg_base 540 541 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 542 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 543 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL) 544 545 lw t0,0(reg_src) 546#ifdef __MIPSEB 547#else 548 srl t0,t0,16 /* (AMD_FLASH_DEVCODE16B*8)*/ 549#endif 550 551 sb t0,0(reg_dest) 552 li t0,AMD_FLASH_RESET 553 sb t0,0(reg_src) 554 555 b nextinst 556/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 55799: bne reg_op,FEOP_AMD_MANID8,99f /* AMD 8-bit - Boot Block Location */ 558 559 ADD reg_src,reg_src,reg_base 560 561 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 562 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 563 FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL) 564 565 lbu t0,AMD_FLASH_MANID(reg_src) 566 sb t0,0(reg_dest) 567 li t0,AMD_FLASH_RESET 568 sb t0,0(reg_src) 569 570 571 b nextinst 572/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 57399: bne reg_op,FEOP_AMD_MANID16,99f /* AMD 8-bit - Boot Block Location */ 574 575 ADD reg_src,reg_src,reg_base 576 577 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 578 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 579 FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL) 580 581 lw t0,0(reg_src) 582#ifdef __MIPSEB 583 srl t0,t0,((3-AMD_FLASH_MANID)*8) 584#else 585 srl t0,t0,(AMD_FLASH_MANID*8) 586#endif 587 sb t0,0(reg_dest) 588 li t0,AMD_FLASH_RESET 589 sb t0,0(reg_src) 590 591 b nextinst 592/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 59399: bne reg_op,FEOP_AMD_MANID16B,99f /* AMD 8-bit - Boot Block Location */ 594 595 ADD reg_src,reg_src,reg_base 596 597 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1) 598 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2) 599 FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL) 600 601 lbu t0,AMD_FLASH_MANID(reg_src) 602 603 sb t0,0(reg_dest) 604 li t0,AMD_FLASH_RESET 605 sb t0,0(reg_src) 606 607 b nextinst 608 609#endif 610 611/* INTEL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 612#if (FLASH_DRIVERS & FLASH_DRIVER_INTEL) 61399: bne reg_op,FEOP_INTEL_ERASE8,99f /* Intel erase 8-bit */ 614 615 ADD reg_dest,reg_dest,reg_base 616 617 FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK) 618 FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM) 619 6201: lbu t0,0(reg_dest) /* loop till bit 7 is set */ 621 andi t0,0x80 622 beq t0,zero,1b 623 624 FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE) 625 626 b nextinst 627/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 62899: bne reg_op,FEOP_INTEL_ERASE16,99f /* Intel erase 16-bit */ 629 630 ADD reg_dest,reg_dest,reg_base 631 632 633 FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK) 634 FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM) 635 6361: lbu t0,0(reg_dest) /* loop till bit 7 is set */ 637 andi t0,0x80 638 beq t0,zero,1b 639 640 FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE) 641 642 b nextinst 643/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 64499: bne reg_op,FEOP_INTEL_PGM8,99f /* Intel 8-bit program */ 645 646 ADD reg_dest,reg_dest,reg_base 647 64811: FLASHCMD_8(reg_dest,0,INTEL_FLASH_PROGRAM) 649 650 lbu t0,0(reg_src) 651 sb t0,0(reg_dest) 652 6531: lbu t0,0(reg_dest) /* loop till bit 7 is set */ 654 andi t0,0x80 655 beq t0,zero,1b 656 657 lbu t0,0(reg_dest) /* contains final result */ 658 /* If good, bits 1, 3, 4 will not be set */ 659 660 add reg_src,1 661 ADD reg_dest,1 662 sub reg_cnt,1 663 bgt reg_cnt,zero,11b 664 665 FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE) 666 667 b nextinst 668/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 66999: bne reg_op,FEOP_INTEL_PGM16,99f /* Intel 16-bit prog */ 670 671 ADD reg_dest,reg_dest,reg_base 672 67311: FLASHCMD_16(reg_dest,0,INTEL_FLASH_PROGRAM) 674 675 lh t0,0(reg_src) 676 sh t0,0(reg_dest) 677 6781: lh t0,0(reg_dest) /* loop till bit 7 is set */ 679 andi t0,0x80 680 beq t0,zero,1b 681 682 lh t0,0(reg_dest) /* contains final result */ 683 /* If good, bits 1, 3, 4 will not be set */ 684 685 FLASHCMD_16(reg_dest,0,INTEL_FLASH_READ_MODE) 686 687 add reg_src,2 688 ADD reg_dest,2 689 sub reg_cnt,2 690 bgt reg_cnt,zero,11b 691 692 b nextinst 693#endif 694/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 695#if (FLASH_DRIVERS & FLASH_DRIVER_SST) 69699: bne reg_op,FEOP_SST_CFIQUERY16,99f /* SST CFI Query 16-bit in word mode */ 697 698 ADD reg_src,reg_src,reg_base 699 700 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1) 701 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2) 702 703 FLASHCMD_16(reg_base,0x5555,FLASH_CFI_QUERY_MODE) 704 7051: lh t0,0(reg_src) /* Copy CFI data */ 706 sb t0,0(reg_dest) 707 ADD reg_src,2 708 add reg_dest,2 709 sub reg_cnt,2 710 bgt reg_cnt,zero,1b 711 712 FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,SST_FLASH_RESET) 713 714 b nextinst 715/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 71699: bne reg_op,FEOP_SST_ERASE16,99f /* SST erase (16-bit in word mode) */ 717 718 ADD reg_dest,reg_dest,reg_base 719 720 /* Do an "unlock write" sequence (cycles 1-2) */ 721 722 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1) 723 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2) 724 725 /* send the erase command (cycle 3) */ 726 727 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_ERASE_3) 728 729 /* Do an "unlock write" sequence (cycles 4-5) */ 730 731 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1) 732 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2) 733 734 /* Send the "erase sector" qualifier (cycle 6) */ 735 736 FLASHCMD_16(reg_dest,0,SST_FLASH_ERASE_SEC_6) 737 738 /* Wait for the erase to complete */ 739 7401: lh t0,0(reg_dest) # get word 741 and t0,0xFF # test byte 742 bne t0,0xFF,1b # go till erased 743 744 b nextinst 745/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 74699: bne reg_op,FEOP_SST_PGM16,99f /* SST 16-bit program */ 747 748 ADD reg_dest,reg_dest,reg_base 749 750 /* Do an "unlock write" sequence (cycles 1-2) */ 75111: 752 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_MAGIC_1) 753 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_2,SST_FLASH_MAGIC_2) 754 755 /* Send a program command (cycle 3) */ 756 757 FLASHCMD_16(reg_base,SST_FLASH_MAGIC_ADDR_1,SST_FLASH_PROGRAM) 758 759 /* Write a short (cycle 4) */ 760 761 lh t0,0(reg_src) 762 sh t0,0(reg_dest) # t0 = byte written to flash 763 764 /* Wait for write to complete */ 765 7661: lh t2,0(reg_dest) # t2 = byte from flash 767 768 and t1,t2,0x80 # done if bit7 of flash 769 and t0,t0,0x80 # is same as bit7 of data 770 bne t1,t0,1b 771 772 773 /* next short... */ 774 775 add reg_src,2 # next source word 776 ADD reg_dest,2 # next dest word 777 sub reg_cnt,2 # one less count 778 bgt reg_cnt,0,11b 779 780 b nextinst 781#endif 782/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 78399: li v1,-1 /* invalid command */ 784 785nextinst: SR v1,FEINST_RESULT(a0) /* store result of instruction */ 786 ADD v0,v0,v1 /* add to total */ 787 ADD a0,FEINST_SIZE /* advance to next instr. */ 788 b instloop 789 790flashop_engine_end: 791 nop 792 793END(flashop_engine) 794 795 .sdata 796 797 .globl flashop_engine_ptr 798 .globl flashop_engine_len 799 800flashop_engine_ptr: 801 _VECT_ flashop_engine 802flashop_engine_len: 803 .word flashop_engine_end-flashop_engine 804 805 806 807/* ********************************************************************* 808 * end 809 ********************************************************************* */ 810 811 812