1 /*- 2 * Copyright (c) 2007, Juniper Networks, Inc. 3 * Copyright (c) 2012-2013, SRI International 4 * All rights reserved. 5 * 6 * Portions of this software were developed by SRI International and the 7 * University of Cambridge Computer Laboratory under DARPA/AFRL contract 8 * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research 9 * programme. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the author nor the names of any co-contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 38 39 #include "opt_cfi.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/bus.h> 44 #include <sys/conf.h> 45 #include <sys/endian.h> 46 #include <sys/kenv.h> 47 #include <sys/kernel.h> 48 #include <sys/malloc.h> 49 #include <sys/module.h> 50 #include <sys/rman.h> 51 #include <sys/sysctl.h> 52 53 #include <machine/bus.h> 54 55 #include <dev/cfi/cfi_reg.h> 56 #include <dev/cfi/cfi_var.h> 57 58 static void cfi_add_sysctls(struct cfi_softc *); 59 60 extern struct cdevsw cfi_cdevsw; 61 62 char cfi_driver_name[] = "cfi"; 63 devclass_t cfi_devclass; 64 devclass_t cfi_diskclass; 65 66 uint32_t 67 cfi_read_raw(struct cfi_softc *sc, u_int ofs) 68 { 69 uint32_t val; 70 71 ofs &= ~(sc->sc_width - 1); 72 switch (sc->sc_width) { 73 case 1: 74 val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs); 75 break; 76 case 2: 77 val = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs); 78 break; 79 case 4: 80 val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs); 81 break; 82 default: 83 val = ~0; 84 break; 85 } 86 return (val); 87 } 88 89 uint32_t 90 cfi_read(struct cfi_softc *sc, u_int ofs) 91 { 92 uint32_t val; 93 uint16_t sval; 94 95 ofs &= ~(sc->sc_width - 1); 96 switch (sc->sc_width) { 97 case 1: 98 val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs); 99 break; 100 case 2: 101 sval = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs); 102 #ifdef CFI_HARDWAREBYTESWAP 103 val = sval; 104 #else 105 val = le16toh(sval); 106 #endif 107 break; 108 case 4: 109 val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs); 110 #ifndef CFI_HARDWAREBYTESWAP 111 val = le32toh(val); 112 #endif 113 break; 114 default: 115 val = ~0; 116 break; 117 } 118 return (val); 119 } 120 121 static void 122 cfi_write(struct cfi_softc *sc, u_int ofs, u_int val) 123 { 124 125 ofs &= ~(sc->sc_width - 1); 126 switch (sc->sc_width) { 127 case 1: 128 bus_space_write_1(sc->sc_tag, sc->sc_handle, ofs, val); 129 break; 130 case 2: 131 #ifdef CFI_HARDWAREBYTESWAP 132 bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, val); 133 #else 134 bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, htole16(val)); 135 136 #endif 137 break; 138 case 4: 139 #ifdef CFI_HARDWAREBYTESWAP 140 bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, val); 141 #else 142 bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, htole32(val)); 143 #endif 144 break; 145 } 146 } 147 148 uint8_t 149 cfi_read_qry(struct cfi_softc *sc, u_int ofs) 150 { 151 uint8_t val; 152 153 cfi_write(sc, CFI_QRY_CMD_ADDR * sc->sc_width, CFI_QRY_CMD_DATA); 154 val = cfi_read(sc, ofs * sc->sc_width); 155 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 156 return (val); 157 } 158 159 static void 160 cfi_amd_write(struct cfi_softc *sc, u_int ofs, u_int addr, u_int data) 161 { 162 163 cfi_write(sc, ofs + AMD_ADDR_START, CFI_AMD_UNLOCK); 164 cfi_write(sc, ofs + AMD_ADDR_ACK, CFI_AMD_UNLOCK_ACK); 165 cfi_write(sc, ofs + addr, data); 166 } 167 168 static char * 169 cfi_fmtsize(uint32_t sz) 170 { 171 static char buf[8]; 172 static const char *sfx[] = { "", "K", "M", "G" }; 173 int sfxidx; 174 175 sfxidx = 0; 176 while (sfxidx < 3 && sz > 1023) { 177 sz /= 1024; 178 sfxidx++; 179 } 180 181 sprintf(buf, "%u%sB", sz, sfx[sfxidx]); 182 return (buf); 183 } 184 185 int 186 cfi_probe(device_t dev) 187 { 188 char desc[80]; 189 struct cfi_softc *sc; 190 char *vend_str; 191 int error; 192 uint16_t iface, vend; 193 194 sc = device_get_softc(dev); 195 sc->sc_dev = dev; 196 197 sc->sc_rid = 0; 198 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, 199 RF_ACTIVE); 200 if (sc->sc_res == NULL) 201 return (ENXIO); 202 203 sc->sc_tag = rman_get_bustag(sc->sc_res); 204 sc->sc_handle = rman_get_bushandle(sc->sc_res); 205 206 if (sc->sc_width == 0) { 207 sc->sc_width = 1; 208 while (sc->sc_width <= 4) { 209 if (cfi_read_qry(sc, CFI_QRY_IDENT) == 'Q') 210 break; 211 sc->sc_width <<= 1; 212 } 213 } else if (cfi_read_qry(sc, CFI_QRY_IDENT) != 'Q') { 214 error = ENXIO; 215 goto out; 216 } 217 if (sc->sc_width > 4) { 218 error = ENXIO; 219 goto out; 220 } 221 222 /* We got a Q. Check if we also have the R and the Y. */ 223 if (cfi_read_qry(sc, CFI_QRY_IDENT + 1) != 'R' || 224 cfi_read_qry(sc, CFI_QRY_IDENT + 2) != 'Y') { 225 error = ENXIO; 226 goto out; 227 } 228 229 /* Get the vendor and command set. */ 230 vend = cfi_read_qry(sc, CFI_QRY_VEND) | 231 (cfi_read_qry(sc, CFI_QRY_VEND + 1) << 8); 232 233 sc->sc_cmdset = vend; 234 235 switch (vend) { 236 case CFI_VEND_AMD_ECS: 237 case CFI_VEND_AMD_SCS: 238 vend_str = "AMD/Fujitsu"; 239 break; 240 case CFI_VEND_INTEL_ECS: 241 vend_str = "Intel/Sharp"; 242 break; 243 case CFI_VEND_INTEL_SCS: 244 vend_str = "Intel"; 245 break; 246 case CFI_VEND_MITSUBISHI_ECS: 247 case CFI_VEND_MITSUBISHI_SCS: 248 vend_str = "Mitsubishi"; 249 break; 250 default: 251 vend_str = "Unknown vendor"; 252 break; 253 } 254 255 /* Get the device size. */ 256 sc->sc_size = 1U << cfi_read_qry(sc, CFI_QRY_SIZE); 257 258 /* Sanity-check the I/F */ 259 iface = cfi_read_qry(sc, CFI_QRY_IFACE) | 260 (cfi_read_qry(sc, CFI_QRY_IFACE + 1) << 8); 261 262 /* 263 * Adding 1 to iface will give us a bit-wise "switch" 264 * that allows us to test for the interface width by 265 * testing a single bit. 266 */ 267 iface++; 268 269 error = (iface & sc->sc_width) ? 0 : EINVAL; 270 if (error) 271 goto out; 272 273 snprintf(desc, sizeof(desc), "%s - %s", vend_str, 274 cfi_fmtsize(sc->sc_size)); 275 device_set_desc_copy(dev, desc); 276 277 out: 278 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); 279 return (error); 280 } 281 282 int 283 cfi_attach(device_t dev) 284 { 285 struct cfi_softc *sc; 286 u_int blksz, blocks; 287 u_int r, u; 288 uint64_t mtoexp, ttoexp; 289 #ifdef CFI_SUPPORT_STRATAFLASH 290 uint64_t ppr; 291 char name[KENV_MNAMELEN], value[32]; 292 #endif 293 294 sc = device_get_softc(dev); 295 sc->sc_dev = dev; 296 297 sc->sc_rid = 0; 298 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, 299 #ifndef ATSE_CFI_HACK 300 RF_ACTIVE); 301 #else 302 RF_ACTIVE | RF_SHAREABLE); 303 #endif 304 if (sc->sc_res == NULL) 305 return (ENXIO); 306 307 sc->sc_tag = rman_get_bustag(sc->sc_res); 308 sc->sc_handle = rman_get_bushandle(sc->sc_res); 309 310 /* Get time-out values for erase, write, and buffer write. */ 311 ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_ERASE); 312 mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_ERASE); 313 if (ttoexp == 0) { 314 device_printf(dev, "erase timeout == 0, using 2^16ms\n"); 315 ttoexp = 16; 316 } 317 if (ttoexp > 41) { 318 device_printf(dev, "insane timeout: 2^%jdms\n", ttoexp); 319 return (EINVAL); 320 } 321 if (mtoexp == 0) { 322 device_printf(dev, "max erase timeout == 0, using 2^%jdms\n", 323 ttoexp + 4); 324 mtoexp = 4; 325 } 326 if (ttoexp + mtoexp > 41) { 327 device_printf(dev, "insane max erase timeout: 2^%jd\n", 328 ttoexp + mtoexp); 329 return (EINVAL); 330 } 331 sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] = SBT_1MS * (1ULL << ttoexp); 332 sc->sc_max_timeouts[CFI_TIMEOUT_ERASE] = 333 sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] * (1ULL << mtoexp); 334 335 ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_WRITE); 336 mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_WRITE); 337 if (ttoexp == 0) { 338 device_printf(dev, "write timeout == 0, using 2^18ns\n"); 339 ttoexp = 18; 340 } 341 if (ttoexp > 51) { 342 device_printf(dev, "insane write timeout: 2^%jdus\n", ttoexp); 343 return (EINVAL); 344 } 345 if (mtoexp == 0) { 346 device_printf(dev, "max write timeout == 0, using 2^%jdms\n", 347 ttoexp + 4); 348 mtoexp = 4; 349 } 350 if (ttoexp + mtoexp > 51) { 351 device_printf(dev, "insane max write timeout: 2^%jdus\n", 352 ttoexp + mtoexp); 353 return (EINVAL); 354 } 355 sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] = SBT_1US * (1ULL << ttoexp); 356 sc->sc_max_timeouts[CFI_TIMEOUT_WRITE] = 357 sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] * (1ULL << mtoexp); 358 359 ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE); 360 mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE); 361 /* Don't check for 0, it means not-supported. */ 362 if (ttoexp > 51) { 363 device_printf(dev, "insane write timeout: 2^%jdus\n", ttoexp); 364 return (EINVAL); 365 } 366 if (ttoexp + mtoexp > 51) { 367 device_printf(dev, "insane max write timeout: 2^%jdus\n", 368 ttoexp + mtoexp); 369 return (EINVAL); 370 } 371 sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] = 372 SBT_1US * (1ULL << cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE)); 373 sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE] = 374 sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] * 375 (1ULL << cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE)); 376 377 /* Get the maximum size of a multibyte program */ 378 if (sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] != 0) 379 sc->sc_maxbuf = 1 << (cfi_read_qry(sc, CFI_QRY_MAXBUF) | 380 cfi_read_qry(sc, CFI_QRY_MAXBUF) << 8); 381 else 382 sc->sc_maxbuf = 0; 383 384 /* Get erase regions. */ 385 sc->sc_regions = cfi_read_qry(sc, CFI_QRY_NREGIONS); 386 sc->sc_region = malloc(sc->sc_regions * sizeof(struct cfi_region), 387 M_TEMP, M_WAITOK | M_ZERO); 388 for (r = 0; r < sc->sc_regions; r++) { 389 blocks = cfi_read_qry(sc, CFI_QRY_REGION(r)) | 390 (cfi_read_qry(sc, CFI_QRY_REGION(r) + 1) << 8); 391 sc->sc_region[r].r_blocks = blocks + 1; 392 393 blksz = cfi_read_qry(sc, CFI_QRY_REGION(r) + 2) | 394 (cfi_read_qry(sc, CFI_QRY_REGION(r) + 3) << 8); 395 sc->sc_region[r].r_blksz = (blksz == 0) ? 128 : 396 blksz * 256; 397 } 398 399 /* Reset the device to a default state. */ 400 cfi_write(sc, 0, CFI_BCS_CLEAR_STATUS); 401 402 if (bootverbose) { 403 device_printf(dev, "["); 404 for (r = 0; r < sc->sc_regions; r++) { 405 printf("%ux%s%s", sc->sc_region[r].r_blocks, 406 cfi_fmtsize(sc->sc_region[r].r_blksz), 407 (r == sc->sc_regions - 1) ? "]\n" : ","); 408 } 409 } 410 411 u = device_get_unit(dev); 412 sc->sc_nod = make_dev(&cfi_cdevsw, u, UID_ROOT, GID_WHEEL, 0600, 413 "%s%u", cfi_driver_name, u); 414 sc->sc_nod->si_drv1 = sc; 415 416 cfi_add_sysctls(sc); 417 418 #ifdef CFI_SUPPORT_STRATAFLASH 419 /* 420 * Store the Intel factory PPR in the environment. In some 421 * cases it is the most unique ID on a board. 422 */ 423 if (cfi_intel_get_factory_pr(sc, &ppr) == 0) { 424 if (snprintf(name, sizeof(name), "%s.factory_ppr", 425 device_get_nameunit(dev)) < (sizeof(name) - 1) && 426 snprintf(value, sizeof(value), "0x%016jx", ppr) < 427 (sizeof(value) - 1)) 428 (void) kern_setenv(name, value); 429 } 430 #endif 431 432 device_add_child(dev, "cfid", -1); 433 bus_generic_attach(dev); 434 435 return (0); 436 } 437 438 static void 439 cfi_add_sysctls(struct cfi_softc *sc) 440 { 441 struct sysctl_ctx_list *ctx; 442 struct sysctl_oid_list *children; 443 444 ctx = device_get_sysctl_ctx(sc->sc_dev); 445 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)); 446 447 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 448 "typical_erase_timout_count", 449 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_ERASE], 450 0, "Number of times the typical erase timeout was exceeded"); 451 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 452 "max_erase_timout_count", 453 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_ERASE], 0, 454 "Number of times the maximum erase timeout was exceeded"); 455 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 456 "typical_write_timout_count", 457 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_WRITE], 0, 458 "Number of times the typical write timeout was exceeded"); 459 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 460 "max_write_timout_count", 461 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_WRITE], 0, 462 "Number of times the maximum write timeout was exceeded"); 463 if (sc->sc_maxbuf > 0) { 464 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 465 "typical_bufwrite_timout_count", 466 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_BUFWRITE], 0, 467 "Number of times the typical buffered write timeout was " 468 "exceeded"); 469 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 470 "max_bufwrite_timout_count", 471 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_BUFWRITE], 0, 472 "Number of times the maximum buffered write timeout was " 473 "exceeded"); 474 } 475 } 476 477 int 478 cfi_detach(device_t dev) 479 { 480 struct cfi_softc *sc; 481 482 sc = device_get_softc(dev); 483 484 destroy_dev(sc->sc_nod); 485 free(sc->sc_region, M_TEMP); 486 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); 487 return (0); 488 } 489 490 static int 491 cfi_wait_ready(struct cfi_softc *sc, u_int ofs, sbintime_t start, 492 enum cfi_wait_cmd cmd) 493 { 494 int done, error, tto_exceeded; 495 uint32_t st0 = 0, st = 0; 496 sbintime_t now; 497 498 done = 0; 499 error = 0; 500 tto_exceeded = 0; 501 while (!done && !error) { 502 /* 503 * Save time before we start so we always do one check 504 * after the timeout has expired. 505 */ 506 now = sbinuptime(); 507 508 switch (sc->sc_cmdset) { 509 case CFI_VEND_INTEL_ECS: 510 case CFI_VEND_INTEL_SCS: 511 st = cfi_read(sc, ofs); 512 done = (st & CFI_INTEL_STATUS_WSMS); 513 if (done) { 514 /* NB: bit 0 is reserved */ 515 st &= ~(CFI_INTEL_XSTATUS_RSVD | 516 CFI_INTEL_STATUS_WSMS | 517 CFI_INTEL_STATUS_RSVD); 518 if (st & CFI_INTEL_STATUS_DPS) 519 error = EPERM; 520 else if (st & CFI_INTEL_STATUS_PSLBS) 521 error = EIO; 522 else if (st & CFI_INTEL_STATUS_ECLBS) 523 error = ENXIO; 524 else if (st) 525 error = EACCES; 526 } 527 break; 528 case CFI_VEND_AMD_SCS: 529 case CFI_VEND_AMD_ECS: 530 st0 = cfi_read(sc, ofs); 531 st = cfi_read(sc, ofs); 532 done = ((st & 0x40) == (st0 & 0x40)) ? 1 : 0; 533 break; 534 } 535 536 if (tto_exceeded || 537 now > start + sc->sc_typical_timeouts[cmd]) { 538 if (!tto_exceeded) { 539 tto_exceeded = 1; 540 sc->sc_tto_counts[cmd]++; 541 #ifdef CFI_DEBUG_TIMEOUT 542 device_printf(sc->sc_dev, 543 "typical timeout exceeded (cmd %d)", cmd); 544 #endif 545 } 546 if (now > start + sc->sc_max_timeouts[cmd]) { 547 sc->sc_mto_counts[cmd]++; 548 #ifdef CFI_DEBUG_TIMEOUT 549 device_printf(sc->sc_dev, 550 "max timeout exceeded (cmd %d)", cmd); 551 #endif 552 } 553 } 554 } 555 if (!done && !error) 556 error = ETIMEDOUT; 557 if (error) 558 printf("\nerror=%d (st 0x%x st0 0x%x)\n", error, st, st0); 559 return (error); 560 } 561 562 int 563 cfi_write_block(struct cfi_softc *sc) 564 { 565 union { 566 uint8_t *x8; 567 uint16_t *x16; 568 uint32_t *x32; 569 } ptr, cpyprt; 570 register_t intr; 571 int error, i, neederase = 0; 572 uint32_t st; 573 u_int wlen; 574 sbintime_t start; 575 576 /* Intel flash must be unlocked before modification */ 577 switch (sc->sc_cmdset) { 578 case CFI_VEND_INTEL_ECS: 579 case CFI_VEND_INTEL_SCS: 580 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LBS); 581 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_UB); 582 cfi_write(sc, sc->sc_wrofs, CFI_BCS_READ_ARRAY); 583 break; 584 } 585 586 /* Check if an erase is required. */ 587 for (i = 0; i < sc->sc_wrbufsz; i++) 588 if ((sc->sc_wrbuf[i] & sc->sc_wrbufcpy[i]) != sc->sc_wrbuf[i]) { 589 neederase = 1; 590 break; 591 } 592 593 if (neederase) { 594 intr = intr_disable(); 595 start = sbinuptime(); 596 /* Erase the block. */ 597 switch (sc->sc_cmdset) { 598 case CFI_VEND_INTEL_ECS: 599 case CFI_VEND_INTEL_SCS: 600 cfi_write(sc, sc->sc_wrofs, CFI_BCS_BLOCK_ERASE); 601 cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM); 602 break; 603 case CFI_VEND_AMD_SCS: 604 case CFI_VEND_AMD_ECS: 605 cfi_amd_write(sc, sc->sc_wrofs, AMD_ADDR_START, 606 CFI_AMD_ERASE_SECTOR); 607 cfi_amd_write(sc, sc->sc_wrofs, 0, CFI_AMD_BLOCK_ERASE); 608 break; 609 default: 610 /* Better safe than sorry... */ 611 intr_restore(intr); 612 return (ENODEV); 613 } 614 intr_restore(intr); 615 error = cfi_wait_ready(sc, sc->sc_wrofs, start, 616 CFI_TIMEOUT_ERASE); 617 if (error) 618 goto out; 619 } else 620 error = 0; 621 622 /* Write the block using a multibyte write if supported. */ 623 ptr.x8 = sc->sc_wrbuf; 624 cpyprt.x8 = sc->sc_wrbufcpy; 625 if (sc->sc_maxbuf > sc->sc_width) { 626 switch (sc->sc_cmdset) { 627 case CFI_VEND_INTEL_ECS: 628 case CFI_VEND_INTEL_SCS: 629 for (i = 0; i < sc->sc_wrbufsz; i += wlen) { 630 wlen = MIN(sc->sc_maxbuf, sc->sc_wrbufsz - i); 631 632 intr = intr_disable(); 633 634 start = sbinuptime(); 635 do { 636 cfi_write(sc, sc->sc_wrofs + i, 637 CFI_BCS_BUF_PROG_SETUP); 638 if (sbinuptime() > start + sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE]) { 639 error = ETIMEDOUT; 640 goto out; 641 } 642 st = cfi_read(sc, sc->sc_wrofs + i); 643 } while (! (st & CFI_INTEL_STATUS_WSMS)); 644 645 cfi_write(sc, sc->sc_wrofs + i, 646 (wlen / sc->sc_width) - 1); 647 switch (sc->sc_width) { 648 case 1: 649 bus_space_write_region_1(sc->sc_tag, 650 sc->sc_handle, sc->sc_wrofs + i, 651 ptr.x8 + i, wlen); 652 break; 653 case 2: 654 bus_space_write_region_2(sc->sc_tag, 655 sc->sc_handle, sc->sc_wrofs + i, 656 ptr.x16 + i / 2, wlen / 2); 657 break; 658 case 4: 659 bus_space_write_region_4(sc->sc_tag, 660 sc->sc_handle, sc->sc_wrofs + i, 661 ptr.x32 + i / 4, wlen / 4); 662 break; 663 } 664 665 cfi_write(sc, sc->sc_wrofs + i, 666 CFI_BCS_CONFIRM); 667 668 intr_restore(intr); 669 670 error = cfi_wait_ready(sc, sc->sc_wrofs + i, 671 start, CFI_TIMEOUT_BUFWRITE); 672 if (error != 0) 673 goto out; 674 } 675 goto out; 676 default: 677 /* Fall through to single word case */ 678 break; 679 } 680 681 } 682 683 /* Write the block one byte/word at a time. */ 684 for (i = 0; i < sc->sc_wrbufsz; i += sc->sc_width) { 685 686 /* Avoid writing unless we are actually changing bits */ 687 if (!neederase) { 688 switch (sc->sc_width) { 689 case 1: 690 if(*(ptr.x8 + i) == *(cpyprt.x8 + i)) 691 continue; 692 break; 693 case 2: 694 if(*(ptr.x16 + i / 2) == *(cpyprt.x16 + i / 2)) 695 continue; 696 break; 697 case 4: 698 if(*(ptr.x32 + i / 4) == *(cpyprt.x32 + i / 4)) 699 continue; 700 break; 701 } 702 } 703 704 /* 705 * Make sure the command to start a write and the 706 * actual write happens back-to-back without any 707 * excessive delays. 708 */ 709 intr = intr_disable(); 710 711 start = sbinuptime(); 712 switch (sc->sc_cmdset) { 713 case CFI_VEND_INTEL_ECS: 714 case CFI_VEND_INTEL_SCS: 715 cfi_write(sc, sc->sc_wrofs + i, CFI_BCS_PROGRAM); 716 break; 717 case CFI_VEND_AMD_SCS: 718 case CFI_VEND_AMD_ECS: 719 cfi_amd_write(sc, 0, AMD_ADDR_START, CFI_AMD_PROGRAM); 720 break; 721 } 722 switch (sc->sc_width) { 723 case 1: 724 bus_space_write_1(sc->sc_tag, sc->sc_handle, 725 sc->sc_wrofs + i, *(ptr.x8 + i)); 726 break; 727 case 2: 728 bus_space_write_2(sc->sc_tag, sc->sc_handle, 729 sc->sc_wrofs + i, *(ptr.x16 + i / 2)); 730 break; 731 case 4: 732 bus_space_write_4(sc->sc_tag, sc->sc_handle, 733 sc->sc_wrofs + i, *(ptr.x32 + i / 4)); 734 break; 735 } 736 737 intr_restore(intr); 738 739 error = cfi_wait_ready(sc, sc->sc_wrofs, start, 740 CFI_TIMEOUT_WRITE); 741 if (error) 742 goto out; 743 } 744 745 /* error is 0. */ 746 747 out: 748 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 749 750 /* Relock Intel flash */ 751 switch (sc->sc_cmdset) { 752 case CFI_VEND_INTEL_ECS: 753 case CFI_VEND_INTEL_SCS: 754 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LBS); 755 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LB); 756 cfi_write(sc, sc->sc_wrofs, CFI_BCS_READ_ARRAY); 757 break; 758 } 759 return (error); 760 } 761 762 #ifdef CFI_SUPPORT_STRATAFLASH 763 /* 764 * Intel StrataFlash Protection Register Support. 765 * 766 * The memory includes a 128-bit Protection Register that can be 767 * used for security. There are two 64-bit segments; one is programmed 768 * at the factory with a unique 64-bit number which is immutable. 769 * The other segment is left blank for User (OEM) programming. 770 * The User/OEM segment is One Time Programmable (OTP). It can also 771 * be locked to prevent any further writes by setting bit 0 of the 772 * Protection Lock Register (PLR). The PLR can written only once. 773 */ 774 775 static uint16_t 776 cfi_get16(struct cfi_softc *sc, int off) 777 { 778 uint16_t v = bus_space_read_2(sc->sc_tag, sc->sc_handle, off<<1); 779 return v; 780 } 781 782 #ifdef CFI_ARMEDANDDANGEROUS 783 static void 784 cfi_put16(struct cfi_softc *sc, int off, uint16_t v) 785 { 786 bus_space_write_2(sc->sc_tag, sc->sc_handle, off<<1, v); 787 } 788 #endif 789 790 /* 791 * Read the factory-defined 64-bit segment of the PR. 792 */ 793 int 794 cfi_intel_get_factory_pr(struct cfi_softc *sc, uint64_t *id) 795 { 796 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) 797 return EOPNOTSUPP; 798 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); 799 800 cfi_write(sc, 0, CFI_INTEL_READ_ID); 801 *id = ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(0)))<<48 | 802 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(1)))<<32 | 803 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(2)))<<16 | 804 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(3))); 805 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 806 return 0; 807 } 808 809 /* 810 * Read the User/OEM 64-bit segment of the PR. 811 */ 812 int 813 cfi_intel_get_oem_pr(struct cfi_softc *sc, uint64_t *id) 814 { 815 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) 816 return EOPNOTSUPP; 817 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); 818 819 cfi_write(sc, 0, CFI_INTEL_READ_ID); 820 *id = ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(4)))<<48 | 821 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(5)))<<32 | 822 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(6)))<<16 | 823 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(7))); 824 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 825 return 0; 826 } 827 828 /* 829 * Write the User/OEM 64-bit segment of the PR. 830 * XXX should allow writing individual words/bytes 831 */ 832 int 833 cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t id) 834 { 835 #ifdef CFI_ARMEDANDDANGEROUS 836 register_t intr; 837 int i, error; 838 sbintime_t start; 839 #endif 840 841 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) 842 return EOPNOTSUPP; 843 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); 844 845 #ifdef CFI_ARMEDANDDANGEROUS 846 for (i = 7; i >= 4; i--, id >>= 16) { 847 intr = intr_disable(); 848 start = sbinuptime(); 849 cfi_write(sc, 0, CFI_INTEL_PP_SETUP); 850 cfi_put16(sc, CFI_INTEL_PR(i), id&0xffff); 851 intr_restore(intr); 852 error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, 853 CFI_TIMEOUT_WRITE); 854 if (error) 855 break; 856 } 857 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 858 return error; 859 #else 860 device_printf(sc->sc_dev, "%s: OEM PR not set, " 861 "CFI_ARMEDANDDANGEROUS not configured\n", __func__); 862 return ENXIO; 863 #endif 864 } 865 866 /* 867 * Read the contents of the Protection Lock Register. 868 */ 869 int 870 cfi_intel_get_plr(struct cfi_softc *sc, uint32_t *plr) 871 { 872 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) 873 return EOPNOTSUPP; 874 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); 875 876 cfi_write(sc, 0, CFI_INTEL_READ_ID); 877 *plr = cfi_get16(sc, CFI_INTEL_PLR); 878 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 879 return 0; 880 } 881 882 /* 883 * Write the Protection Lock Register to lock down the 884 * user-settable segment of the Protection Register. 885 * NOTE: this operation is not reversible. 886 */ 887 int 888 cfi_intel_set_plr(struct cfi_softc *sc) 889 { 890 #ifdef CFI_ARMEDANDDANGEROUS 891 register_t intr; 892 int error; 893 sbintime_t start; 894 #endif 895 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) 896 return EOPNOTSUPP; 897 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); 898 899 #ifdef CFI_ARMEDANDDANGEROUS 900 /* worthy of console msg */ 901 device_printf(sc->sc_dev, "set PLR\n"); 902 intr = intr_disable(); 903 binuptime(&start); 904 cfi_write(sc, 0, CFI_INTEL_PP_SETUP); 905 cfi_put16(sc, CFI_INTEL_PLR, 0xFFFD); 906 intr_restore(intr); 907 error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, 908 CFI_TIMEOUT_WRITE); 909 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); 910 return error; 911 #else 912 device_printf(sc->sc_dev, "%s: PLR not set, " 913 "CFI_ARMEDANDDANGEROUS not configured\n", __func__); 914 return ENXIO; 915 #endif 916 } 917 #endif /* CFI_SUPPORT_STRATAFLASH */ 918