Changeset 3393
- Timestamp:
- 06/27/08 18:28:34 (3 months ago)
- Location:
- trunk/util/flashrom
- Files:
-
- 5 modified
-
chipset_enable.c (modified) (4 diffs)
-
flash.h (modified) (1 diff)
-
flashrom.c (modified) (1 diff)
-
ichspi.c (modified) (20 diffs)
-
spi.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/util/flashrom/chipset_enable.c
r3348 r3393 190 190 static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name, unsigned long spibar) 191 191 { 192 uint8_t old, new, bbs ;192 uint8_t old, new, bbs, buc; 193 193 uint32_t tmp, gcs; 194 194 void *rcrb; … … 196 196 /* Read the Root Complex Base Address Register (RCBA) */ 197 197 tmp = pci_read_long(dev, 0xf0); 198 198 199 /* Calculate the Root Complex Register Block address */ 199 200 tmp &= 0xffffc000; 200 printf_debug(" Root Complex Register Block address = 0x%x\n", tmp);201 printf_debug("\nRoot Complex Register Block address = 0x%x\n", tmp); 201 202 rcrb = mmap(0, 0x4000, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mem, (off_t)tmp); 202 203 if (rcrb == MAP_FAILED) { … … 213 214 (bbs == 0x3) ? "LPC" : ((bbs == 0x2) ? "PCI" : "SPI")); 214 215 216 buc = *(volatile uint8_t *)(rcrb + 0x3414); 217 printf_debug("Top Swap : %s\n", (buc & 1)?"enabled (A16 inverted)":"not enabled"); 218 215 219 /* SPIBAR is at RCRB+0x3020 for ICH[78] and RCRB+0x3800 for ICH9. */ 216 printf_debug("SPIBAR = 0x%lx\n", tmp + spibar); 217 /* TODO: Dump the SPI config regs */ 220 printf_debug("SPIBAR = 0x%x + 0x%04x\n", tmp, (uint16_t)spibar); 221 222 // Assign Virtual Address 218 223 ich_spibar = rcrb + spibar; 224 225 if (ich7_detected) { 226 int i; 227 printf_debug("0x00: 0x%04x (SPIS)\n", *(uint16_t *)(ich_spibar + 0)); 228 printf_debug("0x02: 0x%04x (SPIC)\n", *(uint16_t *)(ich_spibar + 2)); 229 printf_debug("0x04: 0x%08x (SPIA)\n", *(uint32_t *)(ich_spibar + 4)); 230 for (i=0; i < 8; i++) { 231 int offs; 232 offs = 8 + (i * 8); 233 printf_debug("0x%02x: 0x%08x (SPID%d)\n", offs, *(uint32_t *)(ich_spibar + offs), i); 234 printf_debug("0x%02x: 0x%08x (SPID%d+4)\n", offs+4, *(uint32_t *)(ich_spibar + offs +4), i); 235 } 236 printf_debug("0x50: 0x%08x (BBAR)\n", *(uint32_t *)(ich_spibar + 0x50)); 237 printf_debug("0x54: 0x%04x (PREOP)\n", *(uint16_t *)(ich_spibar + 0x54)); 238 printf_debug("0x56: 0x%04x (OPTYPE)\n", *(uint16_t *)(ich_spibar + 0x56)); 239 printf_debug("0x58: 0x%08x (OPMENU)\n", *(uint32_t *)(ich_spibar + 0x58)); 240 printf_debug("0x5c: 0x%08x (OPMENU+4)\n", *(uint32_t *)(ich_spibar + 0x5c)); 241 for (i=0; i < 4; i++) { 242 int offs; 243 offs = 0x60 + (i * 4); 244 printf_debug("0x%02x: 0x%08x (PBR%d)\n", offs, *(uint32_t *)(ich_spibar + offs), i); 245 } 246 printf_debug("\n"); 247 if ( (*(uint16_t *)ich_spibar) & (1 << 15)) { 248 printf("WARNING: SPI Configuration Lockdown activated.\n"); 249 } 250 } 219 251 220 252 old = pci_read_byte(dev, 0xdc); … … 235 267 } 236 268 269 /* Flag for ICH7 SPI register block */ 270 int ich7_detected = 0; 271 237 272 static int enable_flash_ich7(struct pci_dev *dev, const char *name) 238 273 { 274 ich7_detected = 1; 239 275 return enable_flash_ich_dc_spi(dev, name, 0x3020); 240 276 } 241 277 278 /* Flag for ICH8/ICH9 SPI register block */ 242 279 int ich9_detected = 0; 243 280 -
trunk/util/flashrom/flash.h
r3382 r3393 371 371 int chipset_flash_enable(void); 372 372 void print_supported_chipsets(void); 373 extern int ich7_detected; 373 374 extern int ich9_detected; 374 375 extern void *ich_spibar; -
trunk/util/flashrom/flashrom.c
r3372 r3393 379 379 if (iopl(3) != 0) { 380 380 #endif 381 fprintf(stderr, "ERROR: iopl failed: \"%s\"\n",381 fprintf(stderr, "ERROR: Could not get IO privileges (%s).\nYou need to be root.\n", 382 382 strerror(errno)); 383 383 exit(1); -
trunk/util/flashrom/ichspi.c
r3392 r3393 5 5 * Copyright (C) 2008 Claus Gindhart <claus.gindhart@kontron.com> 6 6 * Copyright (C) 2008 Dominik Geyer <dominik.geyer@kontron.com> 7 * Copyright (C) 2008 coresystems GmbH <info@coresystems.de> 7 8 * 8 9 * This program is free software; you can redistribute it and/or modify … … 43 44 #define MAXDATABYTES 0x40 44 45 45 /*ICH9 controller register definition*/ 46 #define REG_FADDR 0x08 /* 32 Bits */ 47 #define REG_FDATA0 0x10 /* 64 Bytes */ 48 #define REG_SSFS 0x90 /* 08 Bits */ 46 /* ICH9 controller register definition */ 47 #define ICH9_REG_FADDR 0x08 /* 32 Bits */ 48 #define ICH9_REG_FDATA0 0x10 /* 64 Bytes */ 49 50 #define ICH9_REG_SSFS 0x90 /* 08 Bits */ 49 51 #define SSFS_SCIP 0x00000001 50 52 #define SSFS_CDS 0x00000004 51 53 #define SSFS_FCERR 0x00000008 52 54 #define SSFS_AEL 0x00000010 53 #define REG_SSFC 0x91 /* 24 Bits */ 55 56 #define ICH9_REG_SSFC 0x91 /* 24 Bits */ 54 57 #define SSFC_SCGO 0x00000200 55 58 #define SSFC_ACS 0x00000400 … … 62 65 #define SSFC_SCF_20MHZ 0x00000000 63 66 #define SSFC_SCF_33MHZ 0x01000000 64 #define REG_PREOP 0x94 /* 16 Bits */ 65 #define REG_OPTYPE 0x96 /* 16 Bits */ 66 #define REG_OPMENU 0x98 /* 64 BITS */ 67 68 #define ICH9_REG_PREOP 0x94 /* 16 Bits */ 69 #define ICH9_REG_OPTYPE 0x96 /* 16 Bits */ 70 #define ICH9_REG_OPMENU 0x98 /* 64 Bits */ 67 71 68 72 // ICH9R SPI commands … … 71 75 #define SPI_OPCODE_TYPE_READ_WITH_ADDRESS 2 72 76 #define SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS 3 77 78 // ICH7 registers 79 #define ICH7_REG_SPIS 0x00 /* 16 Bits */ 80 #define SPIS_SCIP 0x00000001 81 #define SPIS_CDS 0x00000004 82 #define SPIS_FCERR 0x00000008 83 84 #define ICH7_REG_SPIC 0x02 /* 16 Bits */ 85 #define SPIC_SCGO 0x0002 86 #define SPIC_ACS 0x0004 87 #define SPIC_SPOP 0x0008 88 #define SPIC_DS 0x4000 89 90 #define ICH7_REG_SPIA 0x04 /* 32 Bits */ 91 #define ICH7_REG_SPID0 0x08 /* 64 Bytes */ 92 #define ICH7_REG_PREOP 0x54 /* 16 Bits */ 93 #define ICH7_REG_OPTYPE 0x56 /* 16 Bits */ 94 #define ICH7_REG_OPMENU 0x58 /* 64 Bits */ 73 95 74 96 typedef struct _OPCODE { … … 102 124 { 103 125 volatile uint32_t regval; 104 regval = *(volatile uint32_t *)((uint8_t *) ich_spibar + X); 126 regval = *(volatile uint32_t *) ((uint8_t *) ich_spibar + X); 127 return regval; 128 } 129 130 static inline uint16_t REGREAD16(int X) 131 { 132 volatile uint16_t regval; 133 regval = *(volatile uint16_t *) ((uint8_t *) ich_spibar + X); 105 134 return regval; 106 135 } … … 115 144 uint8_t datalength, uint8_t * data); 116 145 static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, 117 int Offset);146 int offset); 118 147 static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes, 119 int Offset);148 int offset); 120 149 static int ich_spi_erase_block(struct flashchip *flash, int offset); 121 150 … … 148 177 /* 8:16 Prefix Opcode 2 */ 149 178 temp16 |= ((uint16_t) op->preop[1]) << 8; 150 REGWRITE16(REG_PREOP, temp16); 151 152 /*Program Opcode Types 0 - 7 */ 179 if (ich7_detected) { 180 REGWRITE16(ICH7_REG_PREOP, temp16); 181 } else if (ich9_detected) { 182 REGWRITE16(ICH9_REG_PREOP, temp16); 183 } 184 185 /* Program Opcode Types 0 - 7 */ 153 186 temp16 = 0; 154 187 for (a = 0; a < 8; a++) { 155 188 temp16 |= ((uint16_t) op->opcode[a].spi_type) << (a * 2); 156 189 } 157 REGWRITE16(REG_OPTYPE, temp16); 158 159 /*Program Allowable Opcodes 0 - 3 */ 190 191 if (ich7_detected) { 192 REGWRITE16(ICH7_REG_OPTYPE, temp16); 193 } else if (ich9_detected) { 194 REGWRITE16(ICH9_REG_OPTYPE, temp16); 195 } 196 197 198 /* Program Allowable Opcodes 0 - 3 */ 160 199 temp32 = 0; 161 200 for (a = 0; a < 4; a++) { 162 201 temp32 |= ((uint32_t) op->opcode[a].opcode) << (a * 8); 163 202 } 164 REGWRITE32(REG_OPMENU, temp32); 203 204 if (ich7_detected) { 205 REGWRITE32(ICH7_REG_OPMENU, temp32); 206 } else if (ich9_detected) { 207 REGWRITE32(ICH9_REG_OPMENU, temp32); 208 } 209 165 210 166 211 /*Program Allowable Opcodes 4 - 7 */ 167 212 temp32 = 0; 168 213 for (a = 4; a < 8; a++) { 169 temp32 |= ((uint32_t) op->opcode[a].opcode) << ((a - 4) * 8); 170 } 171 REGWRITE32(REG_OPMENU + 4, temp32); 214 temp32 |= 215 ((uint32_t) op->opcode[a].opcode) << ((a - 4) * 8); 216 } 217 218 if (ich7_detected) { 219 REGWRITE32(ICH7_REG_OPMENU + 4, temp32); 220 } else if (ich9_detected) { 221 REGWRITE32(ICH9_REG_OPMENU + 4, temp32); 222 } 172 223 173 224 return 0; 174 225 } 175 226 176 int run_opcode(uint8_t nr, OPCODE op, uint32_t offset, uint8_t datalength,177 uint8_t * data)227 static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, 228 uint8_t datalength, uint8_t * data) 178 229 { 179 230 int write_cmd = 0; 231 int timeout; 180 232 uint32_t temp32; 233 uint16_t temp16; 181 234 uint32_t a; 182 235 … … 188 241 189 242 /* Programm Offset in Flash into FADDR */ 190 REGWRITE32( REG_FADDR, (offset & 0x00FFFFFF)); /*SPI addresses are 24 BIT only */243 REGWRITE32(ICH7_REG_SPIA, (offset & 0x00FFFFFF)); /* SPI addresses are 24 BIT only */ 191 244 192 245 /* Program data into FDATA0 to N */ … … 201 254 202 255 if ((a % 4) == 3) { 203 REGWRITE32(REG_FDATA0 + (a - (a % 4)), temp32); 256 REGWRITE32(ICH7_REG_SPID0 + (a - (a % 4)), 257 temp32); 204 258 } 205 259 } 206 260 if (((a - 1) % 4) != 3) { 207 REGWRITE32(REG_FDATA0 + ((a - 1) - ((a - 1) % 4)), 208 temp32); 261 REGWRITE32(ICH7_REG_SPID0 + 262 ((a - 1) - ((a - 1) % 4)), temp32); 263 } 264 265 } 266 267 /* Assemble SPIS */ 268 temp16 = 0; 269 /* clear error status registers */ 270 temp16 |= (SPIS_CDS + SPIS_FCERR); 271 REGWRITE16(ICH7_REG_SPIS, temp16); 272 273 /* Assemble SPIC */ 274 temp16 = 0; 275 276 if (datalength != 0) { 277 temp16 |= SPIC_DS; 278 temp16 |= ((uint16_t) ((datalength - 1) & 0x3f)) << 8; 279 } 280 281 /* Select opcode */ 282 temp16 |= ((uint16_t) (nr & 0x07)) << 4; 283 284 /* Handle Atomic */ 285 if (op.atomic != 0) { 286 /* Select atomic command */ 287 temp16 |= SPIC_ACS; 288 /* Selct prefix opcode */ 289 if ((op.atomic - 1) == 1) { 290 /*Select prefix opcode 2 */ 291 temp16 |= SPIC_SPOP; 292 } 293 } 294 295 /* Start */ 296 temp16 |= SPIC_SCGO; 297 298 /* write it */ 299 REGWRITE16(ICH7_REG_SPIC, temp16); 300 301 /* wait for cycle complete */ 302 timeout = 1000 * 60; // 60s is a looong timeout. 303 while (((REGREAD16(ICH7_REG_SPIS) & SPIS_CDS) == 0) && --timeout) { 304 myusec_delay(1000); 305 } 306 if (!timeout) { 307 printf_debug("timeout\n"); 308 } 309 310 if ((REGREAD16(ICH7_REG_SPIS) & SPIS_FCERR) != 0) { 311 printf_debug("Transaction error!\n"); 312 return 1; 313 } 314 315 if ((!write_cmd) && (datalength != 0)) { 316 for (a = 0; a < datalength; a++) { 317 if ((a % 4) == 0) { 318 temp32 = REGREAD32(ICH7_REG_SPID0 + (a)); 319 } 320 321 data[a] = 322 (temp32 & (((uint32_t) 0xff) << ((a % 4) * 8))) 323 >> ((a % 4) * 8); 324 } 325 } 326 327 return 0; 328 } 329 330 331 static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, 332 uint8_t datalength, uint8_t * data) 333 { 334 int write_cmd = 0; 335 uint32_t temp32; 336 uint32_t a; 337 338 /* Is it a write command? */ 339 if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS) 340 || (op.spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS)) { 341 write_cmd = 1; 342 } 343 344 /* Programm Offset in Flash into FADDR */ 345 REGWRITE32(ICH9_REG_FADDR, (offset & 0x00FFFFFF)); /* SPI addresses are 24 BIT only */ 346 347 /* Program data into FDATA0 to N */ 348 if (write_cmd && (datalength != 0)) { 349 temp32 = 0; 350 for (a = 0; a < datalength; a++) { 351 if ((a % 4) == 0) { 352 temp32 = 0; 353 } 354 355 temp32 |= ((uint32_t) data[a]) << ((a % 4) * 8); 356 357 if ((a % 4) == 3) { 358 REGWRITE32(ICH9_REG_FDATA0 + (a - (a % 4)), 359 temp32); 360 } 361 } 362 if (((a - 1) % 4) != 3) { 363 REGWRITE32(ICH9_REG_FDATA0 + 364 ((a - 1) - ((a - 1) % 4)), temp32); 209 365 } 210 366 … … 244 400 245 401 /* write it */ 246 REGWRITE32( REG_SSFS, temp32);402 REGWRITE32(ICH9_REG_SSFS, temp32); 247 403 248 404 /*wait for cycle complete */ 249 while ((REGREAD32( REG_SSFS) & SSFS_CDS) == 0) {405 while ((REGREAD32(ICH9_REG_SSFS) & SSFS_CDS) == 0) { 250 406 /*TODO; Do something that this can't lead into an endless loop. but some 251 407 * commands may cause this to be last more than 30 seconds */ 252 408 } 253 409 254 if ((REGREAD32( REG_SSFS) & SSFS_FCERR) != 0) {410 if ((REGREAD32(ICH9_REG_SSFS) & SSFS_FCERR) != 0) { 255 411 printf_debug("Transaction error!\n"); 256 412 return 1; … … 260 416 for (a = 0; a < datalength; a++) { 261 417 if ((a % 4) == 0) { 262 temp32 = REGREAD32( REG_FDATA0 + (a));418 temp32 = REGREAD32(ICH9_REG_FDATA0 + (a)); 263 419 } 264 420 265 421 data[a] = 266 (temp32 & (((uint32_t) 0xff) << ((a % 4) * 8))) >>267 ((a % 4) * 8);422 (temp32 & (((uint32_t) 0xff) << ((a % 4) * 8))) 423 >> ((a % 4) * 8); 268 424 } 269 425 } … … 272 428 } 273 429 430 static int run_opcode(uint8_t nr, OPCODE op, uint32_t offset, 431 uint8_t datalength, uint8_t * data) 432 { 433 if (ich7_detected) 434 return ich7_run_opcode(nr, op, offset, datalength, data); 435 else if (ich9_detected) { 436 return ich9_run_opcode(nr, op, offset, datalength, data); 437 } 438 439 /* If we ever get here, something really weird happened */ 440 return -1; 441 } 442 274 443 static int ich_spi_erase_block(struct flashchip *flash, int offset) 275 444 { 276 printf_debug("Spi_Erase,Offset=%d,sectors=%d\n", offset, 1); 445 printf_debug("ich_spi_erase_block: offset=%d, sectors=%d\n", 446 offset, 1); 277 447 278 448 if (run_opcode(2, curopcodes->opcode[2], offset, 0, NULL) != 0) { … … 286 456 } 287 457 288 static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int Offset)458 static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset) 289 459 { 290 460 int page_size = flash->page_size; … … 292 462 int a; 293 463 294 printf_debug(" Spi_Read,Offset=%d,number=%d,buf=%p\n", Offset, page_size,295 buf);464 printf_debug("ich_spi_read_page: offset=%d, number=%d, buf=%p\n", 465 offset, page_size, buf); 296 466 297 467 for (a = 0; a < page_size; a += MAXDATABYTES) { … … 300 470 if (run_opcode 301 471 (1, curopcodes->opcode[1], 302 Offset + (page_size - remaining), remaining,472 offset + (page_size - remaining), remaining, 303 473 &buf[page_size - remaining]) != 0) { 304 474 printf_debug("Error reading"); … … 309 479 if (run_opcode 310 480 (1, curopcodes->opcode[1], 311 Offset + (page_size - remaining), MAXDATABYTES,481 offset + (page_size - remaining), MAXDATABYTES, 312 482 &buf[page_size - remaining]) != 0) { 313 483 printf_debug("Error reading"); … … 322 492 323 493 static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes, 324 int Offset)494 int offset) 325 495 { 326 496 int page_size = flash->page_size; … … 328 498 int a; 329 499 330 printf_debug(" write_page_ichspi,Offset=%d,number=%d,buf=%p\n", Offset,331 page_size, bytes);500 printf_debug("ich_spi_write_page: offset=%d, number=%d, buf=%p\n", 501 offset, page_size, bytes); 332 502 333 503 for (a = 0; a < page_size; a += MAXDATABYTES) { … … 335 505 if (run_opcode 336 506 (0, curopcodes->opcode[0], 337 Offset + (page_size - remaining), remaining,507 offset + (page_size - remaining), remaining, 338 508 &bytes[page_size - remaining]) != 0) { 339 509 printf_debug("Error writing"); … … 344 514 if (run_opcode 345 515 (0, curopcodes->opcode[0], 346 Offset + (page_size - remaining), MAXDATABYTES,516 offset + (page_size - remaining), MAXDATABYTES, 347 517 &bytes[page_size - remaining]) != 0) { 348 518 printf_debug("Error writing"); -
trunk/util/flashrom/spi.c
r3386 r3393 3 3 * 4 4 * Copyright (C) 2007, 2008 Carl-Daniel Hailfinger 5 * Copyright (C) 2008 coresystems GmbH 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify … … 36 37 if (it8716f_flashport) 37 38 return it8716f_spi_command(writecnt, readcnt, writearr, readarr); 39 else if (ich7_detected) 40 return ich_spi_command(writecnt, readcnt, writearr, readarr); 38 41 else if (ich9_detected) 39 42 return ich_spi_command(writecnt, readcnt, writearr, readarr); … … 358 361 if (it8716f_flashport) 359 362 return it8716f_spi_chip_read(flash, buf); 363 else if (ich7_detected) 364 return ich_spi_read(flash, buf); 360 365 else if (ich9_detected) 361 366 return ich_spi_read(flash, buf); … … 368 373 if (it8716f_flashport) 369 374 return it8716f_spi_chip_write(flash, buf); 375 else if (ich7_detected) 376 return ich_spi_write(flash, buf); 370 377 else if (ich9_detected) 371 378 return ich_spi_write(flash, buf);
