summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-06-07 21:09:14 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-07-19 13:43:38 +0100
commit2fce0a98f8b3f0efd15cc1463430023f739dab30 (patch)
tree452b343b8ca9080465c55e36abee55900c077067
parentc72f9c6d0f35e07546e5c045313b6d5984f4e0ca (diff)
downloadrockbox-2fce0a98f8.tar.gz
rockbox-2fce0a98f8.zip
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
-rw-r--r--bootloader/x1000/recovery.c1
-rw-r--r--bootloader/x1000/utils.c75
-rw-r--r--bootloader/x1000/x1000bootloader.h1
3 files changed, 77 insertions, 0 deletions
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));