From 4d01168b9bcdb8c060604cbd851e4ea13b4aa9b5 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Mon, 30 May 2022 14:08:02 +0100 Subject: x1000: add flash probe tool to bootloader The flash probe mimics the boot ROM's flash read routines and dumps the manufacturer & device IDs and 16-byte parameter data to a file on the SD card. Change-Id: I3d413bd0cc05a9d7f2285b85454420c3e90274e9 --- bootloader/x1000/recovery.c | 1 + bootloader/x1000/utils.c | 73 +++++++++++++++++++++++++ bootloader/x1000/x1000bootloader.h | 1 + firmware/target/mips/ingenic_x1000/nand-x1000.h | 1 + 4 files changed, 76 insertions(+) diff --git a/bootloader/x1000/recovery.c b/bootloader/x1000/recovery.c index c53fa376b9..e6cc041d99 100644 --- a/bootloader/x1000/recovery.c +++ b/bootloader/x1000/recovery.c @@ -68,6 +68,7 @@ static const struct menuitem debug_menu_items[] = { #ifdef HAVE_SCREENDUMP {MENUITEM_ACTION, "Enable screenshots", &screenshot_enable}, #endif + {MENUITEM_ACTION, "Flash info", &show_flash_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 4d3fb69e57..17eb502e1b 100644 --- a/bootloader/x1000/utils.c +++ b/bootloader/x1000/utils.c @@ -31,6 +31,7 @@ #include "linuxboot.h" #include "screendump.h" #include "nand-x1000.h" +#include "sfc-x1000.h" /* Set to true if a SYS_USB_CONNECTED event is seen * Set to false if a SYS_USB_DISCONNECTED event is seen @@ -338,3 +339,75 @@ void dump_entire_flash(void) dump_flash_file("/flash.img", 0, 2048 * 64 * 1024); #endif } + +static void probe_flash(int log_fd) +{ + static uint8_t buffer[CACHEALIGN_UP(32)] CACHEALIGN_ATTR; + + /* Use parameters from maskrom */ + const uint32_t clock_freq = X1000_EXCLK_FREQ; /* a guess */ + const uint32_t dev_conf = jz_orf(SFC_DEV_CONF, + CE_DL(1), HOLD_DL(1), WP_DL(1), + CPHA(0), CPOL(0), + TSH(0), TSETUP(0), THOLD(0), + STA_TYPE_V(1BYTE), CMD_TYPE_V(8BITS), + SMP_DELAY(0)); + const size_t readid_len = 4; + + /* NOTE: This assumes the NAND driver is inactive. If this is not true, + * this will seriously mess up the NAND driver. */ + sfc_open(); + sfc_set_dev_conf(dev_conf); + sfc_set_clock(clock_freq); + + /* Issue reset */ + sfc_exec(NANDCMD_RESET, 0, NULL, 0); + mdelay(10); + + /* Try various read ID commands (cf. Linux's SPI NAND identify routine) */ + sfc_exec(NANDCMD_READID(0, 0), 0, buffer, readid_len|SFC_READ); + fdprintf(log_fd, "readID opcode = %02x %02x %02x %02x\n", + buffer[0], buffer[1], buffer[2], buffer[3]); + + sfc_exec(NANDCMD_READID(1, 0), 0, buffer, readid_len|SFC_READ); + fdprintf(log_fd, "readID address = %02x %02x %02x %02x\n", + buffer[0], buffer[1], buffer[2], buffer[3]); + + sfc_exec(NANDCMD_READID(0, 8), 0, buffer, readid_len|SFC_READ); + fdprintf(log_fd, "readID dummy = %02x %02x %02x %02x\n", + buffer[0], buffer[1], buffer[2], buffer[3]); + + /* Try reading Ingenic SFC boot block */ + sfc_exec(NANDCMD_PAGE_READ(3), 0, NULL, 0); + mdelay(500); + sfc_exec(NANDCMD_READ_CACHE_SLOW(2), 0, buffer, 16|SFC_READ); + + fdprintf(log_fd, "sfc params0 = %02x %02x %02x %02x\n", + buffer[ 0], buffer[ 1], buffer[ 2], buffer[ 3]); + fdprintf(log_fd, "sfc params1 = %02x %02x %02x %02x\n", + buffer[ 4], buffer[ 5], buffer[ 6], buffer[ 7]); + fdprintf(log_fd, "sfc params2 = %02x %02x %02x %02x\n", + buffer[ 8], buffer[ 9], buffer[10], buffer[11]); + fdprintf(log_fd, "sfc params3 = %02x %02x %02x %02x\n", + buffer[12], buffer[13], buffer[14], buffer[15]); + + sfc_close(); +} + +void show_flash_info(void) +{ + if(check_disk(true) != DISK_PRESENT) + return; + + int fd = open("/flash_info.txt", O_WRONLY|O_CREAT|O_TRUNC); + if(fd < 0) { + splashf(5*HZ, "Cannot create log file"); + return; + } + + splashf(0, "Probing flash..."); + probe_flash(fd); + + close(fd); + splashf(3*HZ, "Dumped flash info\nSee flash_info.txt"); +} diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index 81c7f2aaa4..e74a6a3b68 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h @@ -197,6 +197,7 @@ int dump_flash_file(const char* file, uint32_t addr, uint32_t length); void dump_of_player(void); void dump_of_recovery(void); void dump_entire_flash(void); +void show_flash_info(void); void recovery_menu(void) __attribute__((noreturn)); diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.h b/firmware/target/mips/ingenic_x1000/nand-x1000.h index 150361b739..5e6d1f09bc 100644 --- a/firmware/target/mips/ingenic_x1000/nand-x1000.h +++ b/firmware/target/mips/ingenic_x1000/nand-x1000.h @@ -49,6 +49,7 @@ #define NANDCMD_GET_FEATURE SFC_CMD(0x0f, SFC_TMODE_1_1_1, 1, 0, SFC_PFMT_ADDR_FIRST, 1) #define NANDCMD_SET_FEATURE SFC_CMD(0x1f, SFC_TMODE_1_1_1, 1, 0, SFC_PFMT_ADDR_FIRST, 1) #define NANDCMD_PAGE_READ(x) SFC_CMD(0x13, SFC_TMODE_1_1_1, x, 0, SFC_PFMT_ADDR_FIRST, 0) +#define NANDCMD_READ_CACHE_SLOW(x) SFC_CMD(0x03, SFC_TMODE_1_1_1, x, 8, SFC_PFMT_ADDR_FIRST, 1) #define NANDCMD_READ_CACHE(x) SFC_CMD(0x0b, SFC_TMODE_1_1_1, x, 8, SFC_PFMT_ADDR_FIRST, 1) #define NANDCMD_READ_CACHE_x4(x) SFC_CMD(0x6b, SFC_TMODE_1_1_4, x, 8, SFC_PFMT_ADDR_FIRST, 1) #define NANDCMD_PROGRAM_LOAD(x) SFC_CMD(0x02, SFC_TMODE_1_1_1, x, 0, SFC_PFMT_ADDR_FIRST, 1) -- cgit v1.2.3