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
This commit is contained in:
Aidan MacDonald 2022-05-30 14:08:02 +01:00
parent e05aa27124
commit 4d01168b9b
4 changed files with 76 additions and 0 deletions

View file

@ -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

View file

@ -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");
}

View file

@ -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));

View file

@ -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)