int probe_jedec (struct flashchip * flash) { volatile char * bios = flash->virt_addr; unsigned char id1, id2; *(volatile char *) (bios + 0x5555) = 0xAA; *(volatile char *) (bios + 0x2AAA) = 0x55; *(volatile char *) (bios + 0x5555) = 0x90; myusec_delay(10); id1 = *(volatile unsigned char *) bios; id2 = *(volatile unsigned char *) (bios + 0x01); *(volatile char *) (bios + 0x5555) = 0xAA; *(volatile char *) (bios + 0x2AAA) = 0x55; *(volatile char *) (bios + 0x5555) = 0xF0; myusec_delay(10); printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2); if (id1 == flash->manufacture_id && id2 == flash->model_id) return 1; return 0; }
uint8_t wait_lhf00l04(volatile uint8_t *bios) { uint8_t status; uint8_t id1, id2; *bios = 0x70; if ((*bios & 0x80) == 0) { // it's busy while ((*bios & 0x80) == 0) ; } status = *bios; // put another command to get out of status register mode *bios = 0x90; myusec_delay(10); id1 = *(volatile uint8_t *)bios; id2 = *(volatile uint8_t *)(bios + 0x01); // this is needed to jam it out of "read id" mode *(volatile uint8_t *)(bios + 0x5555) = 0xAA; *(volatile uint8_t *)(bios + 0x2AAA) = 0x55; *(volatile uint8_t *)(bios + 0x5555) = 0xF0; return status; }
int erase_lhf00l04_block(struct flashchip *flash, int offset) { volatile uint8_t *bios = flash->virtual_memory + offset; volatile uint8_t *wrprotect = flash->virtual_registers + offset + 2; uint8_t status; // clear status register *bios = 0x50; printf("Erase at %p\n", bios); status = wait_lhf00l04(flash->virtual_memory); print_lhf00l04_status(status); // clear write protect printf("write protect is at %p\n", (wrprotect)); printf("write protect is 0x%x\n", *(wrprotect)); *(wrprotect) = 0; printf("write protect is 0x%x\n", *(wrprotect)); // now start it *(volatile uint8_t *)(bios) = 0x20; *(volatile uint8_t *)(bios) = 0xd0; myusec_delay(10); // now let's see what the register is status = wait_lhf00l04(flash->virtual_memory); print_lhf00l04_status(status); printf("DONE BLOCK 0x%x\n", offset); return (0); }
int probe_lhf00l04(struct flashchip *flash) { volatile uint8_t *bios = flash->virtual_memory; uint8_t id1, id2; #if 0 /* Enter ID mode */ *(volatile uint8_t *)(bios + 0x5555) = 0xAA; *(volatile uint8_t *)(bios + 0x2AAA) = 0x55; *(volatile uint8_t *)(bios + 0x5555) = 0x90; #endif *bios = 0xff; myusec_delay(10); *bios = 0x90; myusec_delay(10); id1 = *(volatile uint8_t *)bios; id2 = *(volatile uint8_t *)(bios + 0x01); /* Leave ID mode */ *(volatile uint8_t *)(bios + 0x5555) = 0xAA; *(volatile uint8_t *)(bios + 0x2AAA) = 0x55; *(volatile uint8_t *)(bios + 0x5555) = 0xF0; myusec_delay(10); printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2); if (id1 != flash->manufacture_id || id2 != flash->model_id) return 0; map_flash_registers(flash); return 1; }
int erase_jedec (struct flashchip * flash) { volatile char * bios = flash->virt_addr; *(volatile char *) (bios + 0x5555) = 0xAA; *(volatile char *) (bios + 0x2AAA) = 0x55; *(volatile char *) (bios + 0x5555) = 0x80; *(volatile char *) (bios + 0x5555) = 0xAA; *(volatile char *) (bios + 0x2AAA) = 0x55; *(volatile char *) (bios + 0x5555) = 0x10; myusec_delay(10); toggle_ready_jedec(bios); return(0); }