From 2fce0a98f8b3f0efd15cc1463430023f739dab30 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 7 Jun 2022 21:09:14 +0100 Subject: x1000: add flash ONFI info dumper to bootloader Dumps parts of the standard ONFI info located at page 0x01 of the OTP area to a file for easy copy'n'pasting. Change-Id: Ie0ba66d27c400737f14deec7c21e9dcb144028a6 --- bootloader/x1000/recovery.c | 1 + bootloader/x1000/utils.c | 75 ++++++++++++++++++++++++++++++++++++++ bootloader/x1000/x1000bootloader.h | 1 + 3 files changed, 77 insertions(+) diff --git a/bootloader/x1000/recovery.c b/bootloader/x1000/recovery.c index e6cc041d99..371500826f 100644 --- a/bootloader/x1000/recovery.c +++ b/bootloader/x1000/recovery.c @@ -69,6 +69,7 @@ static const struct menuitem debug_menu_items[] = { {MENUITEM_ACTION, "Enable screenshots", &screenshot_enable}, #endif {MENUITEM_ACTION, "Flash info", &show_flash_info}, + {MENUITEM_ACTION, "Flash ONFI info", &show_flash_onfi_info}, #ifdef OF_PLAYER_ADDR {MENUITEM_ACTION, "Dump OF player", &dump_of_player}, #endif diff --git a/bootloader/x1000/utils.c b/bootloader/x1000/utils.c index a1d90dedbb..5bad511b23 100644 --- a/bootloader/x1000/utils.c +++ b/bootloader/x1000/utils.c @@ -421,3 +421,78 @@ void show_flash_info(void) close(fd); splashf(3*HZ, "Dumped flash info\nSee flash_info.txt"); } + +static int dump_flash_onfi_info(int fd) +{ + struct nand_drv* ndrv = nand_init(); + nand_lock(ndrv); + + int ret = nand_open(ndrv); + if(ret != NAND_SUCCESS) { + splashf(5*HZ, "NAND open failed\n"); + nand_unlock(ndrv); + return ret; + } + + nand_enable_otp(ndrv, true); + + /* read ONFI parameter page */ + ret = nand_page_read(ndrv, 0x01, ndrv->page_buf); + if(ret != NAND_SUCCESS) { + splashf(5*HZ, "Dump failed\nNAND read error"); + goto out; + } + + uint8_t* buf = ndrv->page_buf; + + fdprintf(fd, "signature = %08lx\n", load_le32(buf)); + fdprintf(fd, "revision = %04x\n", load_le16(buf+4)); + + char strbuf[32]; + memcpy(strbuf, &buf[32], 12); + strbuf[12] = '\0'; + fdprintf(fd, "manufacturer = \"%s\"\n", strbuf); + + memcpy(strbuf, &buf[44], 20); + strbuf[20] = '\0'; + fdprintf(fd, "device model = \"%s\"\n", strbuf); + + fdprintf(fd, "JEDEC mf. id = %02x\n", buf[64]); + + fdprintf(fd, "data bytes per page = %lu\n", load_le32(buf+80)); + fdprintf(fd, "spare bytes per page = %u\n", load_le16(buf+84)); + fdprintf(fd, "pages per block = %lu\n", load_le32(buf+92)); + fdprintf(fd, "blocks per lun = %lu\n", load_le32(buf+96)); + fdprintf(fd, "number of luns = %u\n", buf[100]); + fdprintf(fd, "bits per cell = %u\n", buf[102]); + fdprintf(fd, "max bad blocks = %u\n", load_le16(buf+103)); + fdprintf(fd, "block endurance = %u\n", load_le16(buf+105)); + fdprintf(fd, "programs per page = %u\n", buf[110]); + fdprintf(fd, "page program time = %u\n", load_le16(buf+133)); + fdprintf(fd, "block erase time = %u\n", load_le16(buf+135)); + fdprintf(fd, "page read time = %u\n", load_le16(buf+137)); + + out: + nand_enable_otp(ndrv, false); + nand_close(ndrv); + nand_unlock(ndrv); + return ret; +} + +void show_flash_onfi_info(void) +{ + if(check_disk(true) != DISK_PRESENT) + return; + + int fd = open("/flash_onfi_info.txt", O_WRONLY|O_CREAT|O_TRUNC); + if(fd < 0) { + splashf(5*HZ, "Cannot create log file"); + return; + } + + splashf(0, "Reading ONFI info..."); + dump_flash_onfi_info(fd); + + close(fd); + splashf(3*HZ, "Dumped flash ONFI info\nSee flash_onfi_info.txt"); +} diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index e74a6a3b68..ba2baa33b5 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h @@ -198,6 +198,7 @@ void dump_of_player(void); void dump_of_recovery(void); void dump_entire_flash(void); void show_flash_info(void); +void show_flash_onfi_info(void); void recovery_menu(void) __attribute__((noreturn)); -- cgit v1.2.3