#include <errno.h>
#include <fcntl.h>
-#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
struct pci_access *pacc; /* For board and chipset_enable */
int exclude_start_page, exclude_end_page;
int verbose = 0;
-int fd_mem;
struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
{
return NULL;
}
-int map_flash_registers(struct flashchip *flash)
+void map_flash_registers(struct flashchip *flash)
{
- volatile uint8_t *registers;
size_t size = flash->total_size * 1024;
-
- registers = mmap(0, size, PROT_WRITE | PROT_READ, MAP_SHARED,
- fd_mem, (off_t) (0xFFFFFFFF - 0x400000 - size + 1));
-
- if (registers == MAP_FAILED) {
- perror("Can't mmap registers using " MEM_DEV);
- exit(1);
- }
- flash->virtual_registers = registers;
-
- return 0;
+ flash->virtual_registers = physmap("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
}
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
{
volatile uint8_t *bios;
struct flashchip *flash;
- unsigned long flash_baseaddr = 0, size;
+ unsigned long base = 0, size;
for (flash = first_flash; flash && flash->name; flash++) {
if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
*/
size = getpagesize();
}
-#ifdef TS5300
- // FIXME: Wrong place for this decision
- // FIXME: This should be autodetected. It is trivial.
- flash_baseaddr = 0x9400000;
-#else
- flash_baseaddr = (0xffffffff - size + 1);
-#endif
- bios = mmap(0, size, PROT_WRITE | PROT_READ, MAP_SHARED,
- fd_mem, (off_t) flash_baseaddr);
- if (bios == MAP_FAILED) {
- perror("Can't mmap memory using " MEM_DEV);
- exit(1);
- }
- flash->virtual_memory = bios;
+ base = flashbase ? flashbase : (0xffffffff - size + 1);
+ flash->virtual_memory = bios = physmap("flash chip", base, size);
if (force)
break;
break;
notfound:
- munmap((void *)bios, size);
+ physunmap((void *)bios, size);
}
if (!flash || !flash->name)
return NULL;
printf("Found chip \"%s %s\" (%d KB) at physical address 0x%lx.\n",
- flash->vendor, flash->name, flash->total_size, flash_baseaddr);
+ flash->vendor, flash->name, flash->total_size, base);
+ flashbase = base;
return flash;
}
printf("0x%08x", idx);
if (*(buf2 + idx) != *(buf + idx)) {
- if (verbose) {
- printf("0x%08x ", idx);
- }
- printf("FAILED! Expected=0x%02x, Read=0x%02x\n",
+ if (verbose)
+ printf("0x%08x FAILED!", idx);
+ else
+ printf("FAILED at 0x%08x!", idx);
+ printf(" Expected=0x%02x, Read=0x%02x\n",
*(buf + idx), *(buf2 + idx));
return 1;
}
return 0;
}
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define POS_PRINT(x) do { pos += strlen(x); printf(x); } while (0)
+
void print_supported_chips(void)
{
- int i;
+ int okcol = 0, pos = 0;
+ struct flashchip *f;
- printf("Supported ROM chips:\n\n");
+ for (f = flashchips; f->name != NULL; f++) {
+ if (GENERIC_DEVICE_ID == f->model_id)
+ continue;
+ okcol = MAX(okcol, strlen(f->vendor) + 1 + strlen(f->name));
+ }
+ okcol = (okcol + 7) & ~7;
- for (i = 0; flashchips[i].name != NULL; i++)
- printf("%s %s\n", flashchips[i].vendor, flashchips[i].name);
+ POS_PRINT("Supported flash chips:");
+ while (pos < okcol) {
+ printf("\t");
+ pos += 8 - (pos % 8);
+ }
+ printf("Tested OK operations:\tKnown BAD operations:\n\n");
+
+ for (f = flashchips; f->name != NULL; f++) {
+ printf("%s %s", f->vendor, f->name);
+ pos = strlen(f->vendor) + 1 + strlen(f->name);
+ while (pos < okcol) {
+ printf("\t");
+ pos += 8 - (pos % 8);
+ }
+ if ((f->tested & TEST_OK_MASK)) {
+ if ((f->tested & TEST_OK_PROBE))
+ POS_PRINT("PROBE ");
+ if ((f->tested & TEST_OK_READ))
+ POS_PRINT("READ ");
+ if ((f->tested & TEST_OK_ERASE))
+ POS_PRINT("ERASE ");
+ if ((f->tested & TEST_OK_WRITE))
+ POS_PRINT("WRITE");
+ }
+ while (pos < okcol + 24) {
+ printf("\t");
+ pos += 8 - (pos % 8);
+ }
+ if ((f->tested & TEST_BAD_MASK)) {
+ if ((f->tested & TEST_BAD_PROBE))
+ printf("PROBE ");
+ if ((f->tested & TEST_BAD_READ))
+ printf("READ ");
+ if ((f->tested & TEST_BAD_ERASE))
+ printf("ERASE ");
+ if ((f->tested & TEST_BAD_WRITE))
+ printf("WRITE");
+ }
+ printf("\n");
+ }
}
void usage(const char *name)
int main(int argc, char *argv[])
{
uint8_t *buf;
- unsigned long size;
+ unsigned long size, numbytes;
+ uint32_t erasedbytes;
FILE *image;
/* Probe for up to three flash chips. */
struct flashchip *flash, *flashes[3];
pci_init(pacc); /* Initialize the PCI library */
pci_scan_bus(pacc); /* We want to get the list of devices */
- /* Open the memory device UNCACHED. That's important for MMIO. */
- if ((fd_mem = open(MEM_DEV, O_RDWR | O_SYNC)) < 0) {
- perror("Error: Can not access memory using " MEM_DEV
- ". You need to be root.");
- exit(1);
- }
-
myusec_calibrate_delay();
/* We look at the lbtable first to see if we need a
exclude_end_position -
exclude_start_position);
- fwrite(buf, sizeof(char), size, image);
+ numbytes = fwrite(buf, 1, size, image);
fclose(image);
- printf("done.\n");
+ printf("%s.\n", numbytes == size ? "done" : "FAILED");
free(buf);
- exit(0);
+ return numbytes != size;
}
// FIXME: flash writes stay enabled!
exit(1);
if (erase_it) {
printf("Erasing flash chip... ");
- if (!flash->erase) {
- fprintf(stderr, "Error: flashrom has no erase function for this flash chip.\n");
+ if (NULL == flash->erase) {
+ printf("FAILED!\n");
+ fprintf(stderr, "ERROR: flashrom has no erase function for this flash chip.\n");
return 1;
}
flash->erase(flash);
- printf("done.\n");
- exit(0);
+ if (NULL == flash->read)
+ memcpy(buf, (const char *)flash->virtual_memory, size);
+ else
+ flash->read(flash, buf);
+ for (erasedbytes = 0; erasedbytes < size; erasedbytes++)
+ if (0xff != buf[erasedbytes]) {
+ printf("FAILED!\n");
+ fprintf(stderr, "ERROR at 0x%08x: Expected=0xff, Read=0x%02x\n",
+ erasedbytes, buf[erasedbytes]);
+ return 1;
+ }
+ printf("SUCCESS.\n");
+ return 0;
} else if (read_it) {
if ((image = fopen(filename, "w")) == NULL) {
perror(filename);
memset(buf + exclude_start_position, 0,
exclude_end_position - exclude_start_position);
- fwrite(buf, sizeof(char), size, image);
+ numbytes = fwrite(buf, 1, size, image);
fclose(image);
- printf("done.\n");
+ printf("%s.\n", numbytes == size ? "done" : "FAILED");
+ if (numbytes != size)
+ return 1;
} else {
struct stat image_stat;
exit(1);
}
- fread(buf, sizeof(char), size, image);
+ numbytes = fread(buf, 1, size, image);
show_id(buf, size, force);
fclose(image);
+ if (numbytes != size) {
+ fprintf(stderr, "Error: Failed to read file. Got %ld bytes, wanted %ld!\n", numbytes, size);
+ return 1;
+ }
}
/* exclude range stuff. Nice idea, but at the moment it is only