- Timestamp:
- 11/08/11 11:55:54 (7 months ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
chipset_enable.c (modified) (2 diffs)
-
flashrom.8 (modified) (1 diff)
-
ichspi.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/chipset_enable.c
r1460 r1461 492 492 enum ich_chipset ich_generation) 493 493 { 494 int ret ;494 int ret, ret_spi; 495 495 uint8_t bbs, buc; 496 496 uint32_t tmp, gcs; … … 570 570 571 571 /* This adds BUS_SPI */ 572 if (ich_init_spi(dev, tmp, rcrb, ich_generation) != 0) { 573 if (!ret) 574 ret = ERROR_NONFATAL; 575 } 572 ret_spi = ich_init_spi(dev, tmp, rcrb, ich_generation); 573 if (ret_spi == ERROR_FATAL) 574 return ret_spi; 575 576 if (ret || ret_spi) 577 ret = ERROR_NONFATAL; 576 578 577 579 return ret; -
trunk/flashrom.8
r1453 r1461 304 304 report so we can diagnose the problem. 305 305 .sp 306 If you have an Intel chipset with an ICH8 or later southbridge with SPI flash 307 attached, and if a valid descriptor was written to it (e.g. by the vendor), the 308 chipset provides an alternative way to access the flash chip(s) named 309 .BR "Hardware Sequencing" . 310 It is much simpler than the normal access method (called 311 .BR "Software Sequencing" ")," 312 but does not allow the software to choose the SPI commands to be sent. 313 You can use the 314 .sp 315 .B " flashrom \-p internal:ich_spi_mode=value" 316 .sp 317 syntax where value can be 318 .BR auto ", " swseq " or " hwseq . 319 By default 320 .RB "(or when setting " ich_spi_mode=auto ) 321 the module tries to use swseq and only activates hwseq if need be (e.g. if 322 important opcodes are inaccessible due to lockdown; or if more than one flash 323 chip is attached). The other options (swseq, hwseq) select the respective mode 324 (if possible). 325 .sp 306 326 If you have an Intel chipset with an ICH6 or later southbridge and if you want 307 327 to set specific IDSEL values for a non-default flash chip or an embedded -
trunk/ichspi.c
r1460 r1461 424 424 int a; 425 425 426 if (op == NULL) { 427 msg_perr("\n%s: null OPCODES pointer!\n", __func__); 428 return -1; 429 } 430 426 431 for (a = 0; a < 8; a++) { 427 432 if (op->opcode[a].opcode == opcode) … … 435 440 { 436 441 int a; 442 443 if (op == NULL) { 444 msg_perr("\n%s: null OPCODES pointer!\n", __func__); 445 return -1; 446 } 437 447 438 448 for (a = 0; a < 2; a++) { … … 562 572 563 573 /* 574 * Returns -1 if at least one mandatory opcode is inaccessible, 0 otherwise. 575 * FIXME: this should also check for 576 * - at least one probing opcode (RDID (incl. AT25F variants?), REMS, RES?) 577 * - at least one erasing opcode (lots.) 578 * - at least one program opcode (BYTE_PROGRAM, AAI_WORD_PROGRAM, ...?) 579 * - necessary preops? (EWSR, WREN, ...?) 580 */ 581 static int ich_missing_opcodes() 582 { 583 uint8_t ops[] = { 584 JEDEC_READ, 585 JEDEC_RDSR, 586 0 587 }; 588 int i = 0; 589 while (ops[i] != 0) { 590 msg_pspew("checking for opcode 0x%02x\n", ops[i]); 591 if (find_opcode(curopcodes, ops[i]) == -1) 592 return -1; 593 i++; 594 } 595 return 0; 596 } 597 598 /* 564 599 * Try to set BBAR (BIOS Base Address Register), but read back the value in case 565 600 * it didn't stick. … … 1067 1102 } 1068 1103 1069 #if 0 1104 static struct hwseq_data { 1105 uint32_t size_comp0; 1106 uint32_t size_comp1; 1107 } hwseq_data; 1108 1070 1109 /* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ 1071 1110 static void ich_hwseq_set_addr(uint32_t addr) … … 1118 1157 addr = REGREAD32(ICH9_REG_FADDR) & 0x01FFFFFF; 1119 1158 msg_perr("Timeout error between offset 0x%08x and " 1120 "0x%08x + %d (=0x%08x)!\n", 1121 addr, addr, len - 1, addr + len - 1); 1122 prettyprint_ich9_reg_hsfs(hsfs); 1123 prettyprint_ich9_reg_hsfc(REGREAD16(ICH9_REG_HSFC)); 1124 return 1; 1125 } 1126 1127 if (hsfs & HSFS_FCERR) { 1128 addr = REGREAD32(ICH9_REG_FADDR) & 0x01FFFFFF; 1129 msg_perr("Transaction error between offset 0x%08x and " 1130 "0x%08x (=0x%08x + %d)!\n", 1159 "0x%08x (= 0x%08x + %d)!\n", 1131 1160 addr, addr + len - 1, addr, len - 1); 1132 1161 prettyprint_ich9_reg_hsfs(hsfs); … … 1134 1163 return 1; 1135 1164 } 1165 1166 if (hsfs & HSFS_FCERR) { 1167 addr = REGREAD32(ICH9_REG_FADDR) & 0x01FFFFFF; 1168 msg_perr("Transaction error between offset 0x%08x and " 1169 "0x%08x (= 0x%08x + %d)!\n", 1170 addr, addr + len - 1, addr, len - 1); 1171 prettyprint_ich9_reg_hsfs(hsfs); 1172 prettyprint_ich9_reg_hsfc(REGREAD16(ICH9_REG_HSFC)); 1173 return 1; 1174 } 1136 1175 return 0; 1137 1176 } 1138 #endif 1177 1178 int ich_hwseq_probe(struct flashchip *flash) 1179 { 1180 uint32_t total_size, boundary; 1181 uint32_t erase_size_low, size_low, erase_size_high, size_high; 1182 struct block_eraser *eraser; 1183 1184 total_size = hwseq_data.size_comp0 + hwseq_data.size_comp1; 1185 msg_cdbg("Found %d attached SPI flash chip", 1186 (hwseq_data.size_comp1 != 0) ? 2 : 1); 1187 if (hwseq_data.size_comp1 != 0) 1188 msg_cdbg("s with a combined"); 1189 else 1190 msg_cdbg(" with a"); 1191 msg_cdbg(" density of %d kB.\n", total_size / 1024); 1192 flash->total_size = total_size / 1024; 1193 1194 eraser = &(flash->block_erasers[0]); 1195 boundary = (REGREAD32(ICH9_REG_FPB) & FPB_FPBA) << 12; 1196 size_high = total_size - boundary; 1197 erase_size_high = ich_hwseq_get_erase_block_size(boundary); 1198 1199 if (boundary == 0) { 1200 msg_cdbg("There is only one partition containing the whole " 1201 "address space (0x%06x - 0x%06x).\n", 0, size_high-1); 1202 eraser->eraseblocks[0].size = erase_size_high; 1203 eraser->eraseblocks[0].count = size_high / erase_size_high; 1204 msg_cdbg("There are %d erase blocks with %d B each.\n", 1205 size_high / erase_size_high, erase_size_high); 1206 } else { 1207 msg_cdbg("The flash address space (0x%06x - 0x%06x) is divided " 1208 "at address 0x%06x in two partitions.\n", 1209 0, size_high-1, boundary); 1210 size_low = total_size - size_high; 1211 erase_size_low = ich_hwseq_get_erase_block_size(0); 1212 1213 eraser->eraseblocks[0].size = erase_size_low; 1214 eraser->eraseblocks[0].count = size_low / erase_size_low; 1215 msg_cdbg("The first partition ranges from 0x%06x to 0x%06x.\n", 1216 0, size_low-1); 1217 msg_cdbg("In that range are %d erase blocks with %d B each.\n", 1218 size_low / erase_size_low, erase_size_low); 1219 1220 eraser->eraseblocks[1].size = erase_size_high; 1221 eraser->eraseblocks[1].count = size_high / erase_size_high; 1222 msg_cdbg("The second partition ranges from 0x%06x to 0x%06x.\n", 1223 boundary, size_high-1); 1224 msg_cdbg("In that range are %d erase blocks with %d B each.\n", 1225 size_high / erase_size_high, erase_size_high); 1226 } 1227 flash->tested = TEST_OK_PREW; 1228 return 1; 1229 } 1230 1231 int ich_hwseq_block_erase(struct flashchip *flash, 1232 unsigned int addr, 1233 unsigned int len) 1234 { 1235 uint32_t erase_block; 1236 uint16_t hsfc; 1237 uint32_t timeout = 5000 * 1000; /* 5 s for max 64 kB */ 1238 1239 erase_block = ich_hwseq_get_erase_block_size(addr); 1240 if (len != erase_block) { 1241 msg_cerr("Erase block size for address 0x%06x is %d B, " 1242 "but requested erase block size is %d B. " 1243 "Not erasing anything.\n", addr, erase_block, len); 1244 return -1; 1245 } 1246 1247 /* Although the hardware supports this (it would erase the whole block 1248 * containing the address) we play safe here. */ 1249 if (addr % erase_block != 0) { 1250 msg_cerr("Erase address 0x%06x is not aligned to the erase " 1251 "block boundary (any multiple of %d). " 1252 "Not erasing anything.\n", addr, erase_block); 1253 return -1; 1254 } 1255 1256 if (addr + len > flash->total_size * 1024) { 1257 msg_perr("Request to erase some inaccessible memory address(es)" 1258 " (addr=0x%x, len=%d). " 1259 "Not erasing anything.\n", addr, len); 1260 return -1; 1261 } 1262 1263 msg_pdbg("Erasing %d bytes starting at 0x%06x.\n", len, addr); 1264 1265 /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ 1266 REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); 1267 1268 hsfc = REGREAD16(ICH9_REG_HSFC); 1269 hsfc &= ~HSFC_FCYCLE; /* clear operation */ 1270 hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ 1271 hsfc |= HSFC_FGO; /* start */ 1272 msg_pdbg("HSFC used for block erasing: "); 1273 prettyprint_ich9_reg_hsfc(hsfc); 1274 REGWRITE16(ICH9_REG_HSFC, hsfc); 1275 1276 if (ich_hwseq_wait_for_cycle_complete(timeout, len)) 1277 return -1; 1278 return 0; 1279 } 1280 1281 int ich_hwseq_read(struct flashchip *flash, uint8_t *buf, int addr, int len) 1282 { 1283 uint16_t hsfc; 1284 uint16_t timeout = 100 * 60; 1285 uint8_t block_len; 1286 1287 if (addr < 0 || addr + len > flash->total_size * 1024) { 1288 msg_perr("Request to read from an inaccessible memory address " 1289 "(addr=0x%x, len=%d).\n", addr, len); 1290 return -1; 1291 } 1292 1293 msg_pdbg("Reading %d bytes starting at 0x%06x.\n", len, addr); 1294 /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ 1295 REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); 1296 1297 while (len > 0) { 1298 block_len = min(len, opaque_programmer->max_data_read); 1299 ich_hwseq_set_addr(addr); 1300 hsfc = REGREAD16(ICH9_REG_HSFC); 1301 hsfc &= ~HSFC_FCYCLE; /* set read operation */ 1302 hsfc &= ~HSFC_FDBC; /* clear byte count */ 1303 /* set byte count */ 1304 hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); 1305 hsfc |= HSFC_FGO; /* start */ 1306 REGWRITE16(ICH9_REG_HSFC, hsfc); 1307 1308 if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) 1309 return 1; 1310 ich_read_data(buf, block_len, ICH9_REG_FDATA0); 1311 addr += block_len; 1312 buf += block_len; 1313 len -= block_len; 1314 } 1315 return 0; 1316 } 1317 1318 int ich_hwseq_write(struct flashchip *flash, uint8_t *buf, int addr, int len) 1319 { 1320 uint16_t hsfc; 1321 uint16_t timeout = 100 * 60; 1322 uint8_t block_len; 1323 1324 if (addr < 0 || addr + len > flash->total_size * 1024) { 1325 msg_perr("Request to write to an inaccessible memory address " 1326 "(addr=0x%x, len=%d).\n", addr, len); 1327 return -1; 1328 } 1329 1330 msg_pdbg("Writing %d bytes starting at 0x%06x.\n", len, addr); 1331 /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ 1332 REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); 1333 1334 while (len > 0) { 1335 ich_hwseq_set_addr(addr); 1336 block_len = min(len, opaque_programmer->max_data_write); 1337 ich_fill_data(buf, block_len, ICH9_REG_FDATA0); 1338 hsfc = REGREAD16(ICH9_REG_HSFC); 1339 hsfc &= ~HSFC_FCYCLE; /* clear operation */ 1340 hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ 1341 hsfc &= ~HSFC_FDBC; /* clear byte count */ 1342 /* set byte count */ 1343 hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); 1344 hsfc |= HSFC_FGO; /* start */ 1345 REGWRITE16(ICH9_REG_HSFC, hsfc); 1346 1347 if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) 1348 return -1; 1349 addr += block_len; 1350 buf += block_len; 1351 len -= block_len; 1352 } 1353 return 0; 1354 } 1139 1355 1140 1356 static int ich_spi_send_multicommand(struct spi_command *cmds) … … 1301 1517 }; 1302 1518 1519 static const struct opaque_programmer opaque_programmer_ich_hwseq = { 1520 .max_data_read = 64, 1521 .max_data_write = 64, 1522 .probe = ich_hwseq_probe, 1523 .read = ich_hwseq_read, 1524 .write = ich_hwseq_write, 1525 .erase = ich_hwseq_block_erase, 1526 }; 1527 1303 1528 int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb, 1304 1529 enum ich_chipset ich_gen) … … 1308 1533 uint16_t spibar_offset, tmp2; 1309 1534 uint32_t tmp; 1535 char *arg; 1310 1536 int desc_valid = 0; 1537 struct ich_descriptors desc = {{ 0 }}; 1538 enum ich_spi_mode { 1539 ich_auto, 1540 ich_hwseq, 1541 ich_swseq 1542 } ich_spi_mode = ich_auto; 1311 1543 1312 1544 ich_generation = ich_gen; … … 1314 1546 switch (ich_generation) { 1315 1547 case CHIPSET_ICH_UNKNOWN: 1316 return -1;1548 return ERROR_FATAL; 1317 1549 case CHIPSET_ICH7: 1318 1550 case CHIPSET_ICH8: … … 1330 1562 /* Assign Virtual Address */ 1331 1563 ich_spibar = rcrb + spibar_offset; 1564 1565 ich_init_opcodes(); 1332 1566 1333 1567 switch (ich_generation) { … … 1370 1604 ich_set_bbar(0); 1371 1605 register_spi_programmer(&spi_programmer_ich7); 1372 ich_init_opcodes();1373 1606 break; 1374 1607 case CHIPSET_ICH8: 1375 1608 default: /* Future version might behave the same */ 1609 arg = extract_programmer_param("ich_spi_mode"); 1610 if (arg && !strcmp(arg, "hwseq")) { 1611 ich_spi_mode = ich_hwseq; 1612 msg_pspew("user selected hwseq\n"); 1613 } else if (arg && !strcmp(arg, "swseq")) { 1614 ich_spi_mode = ich_swseq; 1615 msg_pspew("user selected swseq\n"); 1616 } else if (arg && !strcmp(arg, "auto")) { 1617 msg_pspew("user selected auto\n"); 1618 ich_spi_mode = ich_auto; 1619 } else if (arg && !strlen(arg)) { 1620 msg_perr("Missing argument for ich_spi_mode.\n"); 1621 free(arg); 1622 return ERROR_FATAL; 1623 } else if (arg) { 1624 msg_perr("Unknown argument for ich_spi_mode: %s\n", 1625 arg); 1626 free(arg); 1627 return ERROR_FATAL; 1628 } 1629 free(arg); 1630 1376 1631 tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFS); 1377 1632 msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2); … … 1459 1714 msg_pdbg("\n"); 1460 1715 if (desc_valid) { 1461 struct ich_descriptors desc = {{ 0 }};1462 1716 if (read_ich_descriptors_via_fdo(ich_spibar, &desc) == 1463 1717 ICH_RET_OK) 1464 1718 prettyprint_ich_descriptors(CHIPSET_ICH_UNKNOWN, 1465 1719 &desc); 1720 /* If the descriptor is valid and indicates multiple 1721 * flash devices we need to use hwseq to be able to 1722 * access the second flash device. 1723 */ 1724 if (ich_spi_mode == ich_auto && desc.content.NC != 0) { 1725 msg_pinfo("Enabling hardware sequencing due to " 1726 "multiple flash chips detected.\n"); 1727 ich_spi_mode = ich_hwseq; 1728 } 1466 1729 } 1467 register_spi_programmer(&spi_programmer_ich9); 1468 ich_init_opcodes(); 1730 1731 if (ich_spi_mode == ich_auto && ichspi_lock && 1732 ich_missing_opcodes()) { 1733 msg_pinfo("Enabling hardware sequencing because " 1734 "some important opcode is locked.\n"); 1735 ich_spi_mode = ich_hwseq; 1736 } 1737 1738 if (ich_spi_mode == ich_hwseq) { 1739 if (!desc_valid) { 1740 msg_perr("Hardware sequencing was requested " 1741 "but the flash descriptor is not " 1742 "valid. Aborting.\n"); 1743 return ERROR_FATAL; 1744 } 1745 hwseq_data.size_comp0 = getFCBA_component_density(&desc, 0); 1746 hwseq_data.size_comp1 = getFCBA_component_density(&desc, 1); 1747 register_opaque_programmer(&opaque_programmer_ich_hwseq); 1748 } else { 1749 register_spi_programmer(&spi_programmer_ich9); 1750 } 1469 1751 break; 1470 1752 }
Note: See TracChangeset
for help on using the changeset viewer.
