mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
rk27xx: debug menu switch to show NAND SYS over USB
The NAND's SYS volume holds the bootloader's firmware and is hidden unless a build defines HAVE_RK27XX_NAND_SYS. Getting at it, e.g. to replace BASE.RKW, needed a special build. Add "NAND SYS on next USB" to the debug menu. While it is set, the next USB connection shows SYS through the USER drive, as "NAND SYS", and the switch clears when that connection ends. It is decided once per connection, so setting it while connected waits for the next one, and it is held in RAM only. Writes still need FTL_ALLOW_WRITE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: Idda3f1c5e00bea511618021397a6cb3bb0be7361
This commit is contained in:
parent
406a28cc6a
commit
1669e49cd7
4 changed files with 135 additions and 54 deletions
|
|
@ -2910,6 +2910,24 @@ static bool dbg_ftl_scheme(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_PLATFORM & PLATFORM_NATIVE) && defined(CONFIG_NAND) \
|
||||
&& (CONFIG_NAND == NAND_RK27XX) \
|
||||
&& (CONFIG_STORAGE & STORAGE_NAND)
|
||||
#include "ftl-target.h"
|
||||
#endif
|
||||
|
||||
#ifdef FTL_SYS_ON_USB
|
||||
/* The NAND's hidden SYS volume, shown to a USB host in place of USER for
|
||||
* one connection */
|
||||
static bool dbg_nand_sys_usb(void)
|
||||
{
|
||||
ftl_set_sys_on_usb(!ftl_get_sys_on_usb());
|
||||
splashf(HZ, "NAND SYS on next USB %sabled",
|
||||
ftl_get_sys_on_usb() ? "en" : "dis");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****** The menu *********/
|
||||
static const struct {
|
||||
unsigned char *desc; /* string or ID */
|
||||
|
|
@ -2967,6 +2985,9 @@ static const struct {
|
|||
&& !(CONFIG_STORAGE & STORAGE_NAND)
|
||||
{ "View FTL scheme", dbg_ftl_scheme },
|
||||
#endif
|
||||
#ifdef FTL_SYS_ON_USB
|
||||
{ "NAND SYS on next USB", dbg_nand_sys_usb },
|
||||
#endif
|
||||
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
||||
{ "View partitions", dbg_partitions },
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -83,11 +83,7 @@ void nand_get_info(IF_MD(int drive,) struct storage_info *info)
|
|||
(*info).sector_size = SECTOR_SIZE;
|
||||
(*info).num_sectors = ftl_get_sectors(d);
|
||||
(*info).vendor = "Rockchip";
|
||||
#ifdef HAVE_RK27XX_NAND_SYS
|
||||
(*info).product = (d == FTL_DRIVE_SYS) ? "NAND SYS" : "NAND USER";
|
||||
#else
|
||||
(*info).product = "NAND USER";
|
||||
#endif
|
||||
(*info).product = ftl_drive_is_sys(d) ? "NAND SYS" : "NAND USER";
|
||||
(*info).revision = "1.0";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
#include "ftl-target.h"
|
||||
#include "nand-target.h"
|
||||
#include "flash-rk27xx.h"
|
||||
#ifdef FTL_SYS_ON_USB
|
||||
#include "usb.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A
|
||||
#include "ftl-scheme-a.h"
|
||||
|
|
@ -65,13 +68,73 @@ struct idb_info
|
|||
|
||||
static bool ftl_mounted = false;
|
||||
|
||||
#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_B
|
||||
/* The volumes behind the drives. Both are known to the FTL even when SYS
|
||||
* is not a drive. */
|
||||
#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A
|
||||
#define VOL_SYS FTL_A_VOL_SYS
|
||||
#define VOL_USER FTL_A_VOL_USER
|
||||
#else
|
||||
#define VOL_SYS 0
|
||||
#define VOL_USER 1
|
||||
#define NUM_VOLS 2
|
||||
|
||||
/* Scheme B's logical space holds the volumes back to back: SYS, the system
|
||||
* data area, then USER to the end */
|
||||
static uint32_t vol_base[FTL_NUM_DRIVES];
|
||||
static uint32_t vol_size[FTL_NUM_DRIVES];
|
||||
static uint32_t vol_base[NUM_VOLS];
|
||||
static uint32_t vol_size[NUM_VOLS];
|
||||
#endif
|
||||
|
||||
#ifdef FTL_SYS_ON_USB
|
||||
/* Asked for in the debug menu: show SYS through the USER drive while a USB
|
||||
* host has the storage. Decided once per connection, so asking during one
|
||||
* waits for the next, and used up when that connection ends. */
|
||||
static bool sys_requested = false;
|
||||
static enum { USB_VIEW_NONE, USB_VIEW_USER, USB_VIEW_SYS } usb_view;
|
||||
|
||||
static bool sys_on_usb(void)
|
||||
{
|
||||
if (!usb_exclusive_storage())
|
||||
{
|
||||
if (usb_view == USB_VIEW_SYS)
|
||||
{
|
||||
sys_requested = false;
|
||||
}
|
||||
usb_view = USB_VIEW_NONE;
|
||||
}
|
||||
else if (usb_view == USB_VIEW_NONE)
|
||||
{
|
||||
usb_view = sys_requested ? USB_VIEW_SYS : USB_VIEW_USER;
|
||||
}
|
||||
return usb_view == USB_VIEW_SYS;
|
||||
}
|
||||
|
||||
void ftl_set_sys_on_usb(bool on)
|
||||
{
|
||||
sys_requested = on;
|
||||
}
|
||||
|
||||
bool ftl_get_sys_on_usb(void)
|
||||
{
|
||||
return sys_requested;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int drive_volume(int drive)
|
||||
{
|
||||
#ifdef HAVE_RK27XX_NAND_SYS
|
||||
return (drive == FTL_DRIVE_SYS) ? VOL_SYS : VOL_USER;
|
||||
#else
|
||||
(void)drive;
|
||||
#ifdef FTL_SYS_ON_USB
|
||||
if (sys_on_usb())
|
||||
{
|
||||
return VOL_SYS;
|
||||
}
|
||||
#endif
|
||||
return VOL_USER;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ID block 1, the sector after ID block 0:
|
||||
*
|
||||
* +0 uint16_t LE raw blocks of the boot area
|
||||
|
|
@ -179,12 +242,10 @@ static uint32_t mount_scheme(const struct idb_info *idb)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_RK27XX_NAND_SYS
|
||||
vol_base[FTL_DRIVE_SYS] = 0;
|
||||
vol_size[FTL_DRIVE_SYS] = idb->sys_sectors;
|
||||
#endif
|
||||
vol_base[FTL_DRIVE_USER] = user_base;
|
||||
vol_size[FTL_DRIVE_USER] = ftl_b_capacity() - user_base;
|
||||
vol_base[VOL_SYS] = 0;
|
||||
vol_size[VOL_SYS] = idb->sys_sectors;
|
||||
vol_base[VOL_USER] = user_base;
|
||||
vol_size[VOL_USER] = ftl_b_capacity() - user_base;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -219,81 +280,65 @@ static bool drive_valid(int drive)
|
|||
}
|
||||
|
||||
#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A
|
||||
/* The FTL volume behind a drive. SYS is reachable only when exposed. */
|
||||
static int ftl_volume(int drive)
|
||||
static uint32_t vol_sectors(int vol)
|
||||
{
|
||||
int volume = FTL_A_VOL_USER;
|
||||
|
||||
#ifdef HAVE_RK27XX_NAND_SYS
|
||||
if (drive == FTL_DRIVE_SYS)
|
||||
{
|
||||
volume = FTL_A_VOL_SYS;
|
||||
}
|
||||
#else
|
||||
(void)drive;
|
||||
#endif
|
||||
return volume;
|
||||
return ftl_a_capacity(vol);
|
||||
}
|
||||
|
||||
static uint32_t drive_sectors(int drive)
|
||||
static int vol_read(int vol, uint32_t sector, uint32_t count, void *buffer)
|
||||
{
|
||||
return ftl_a_capacity(ftl_volume(drive));
|
||||
}
|
||||
|
||||
static int drive_read(int drive, uint32_t sector, uint32_t count, void *buffer)
|
||||
{
|
||||
return ftl_a_read(ftl_volume(drive), sector, buffer, count);
|
||||
return ftl_a_read(vol, sector, buffer, count);
|
||||
}
|
||||
|
||||
#ifdef FTL_ALLOW_WRITE
|
||||
static int drive_write(int drive, uint32_t sector, uint32_t count,
|
||||
static int vol_write(int vol, uint32_t sector, uint32_t count,
|
||||
const void *buffer)
|
||||
{
|
||||
return ftl_a_write(ftl_volume(drive), sector, buffer, count);
|
||||
return ftl_a_write(vol, sector, buffer, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drive_sync(void)
|
||||
static void vol_sync(void)
|
||||
{
|
||||
ftl_a_sync();
|
||||
}
|
||||
#else
|
||||
static uint32_t drive_sectors(int drive)
|
||||
static uint32_t vol_sectors(int vol)
|
||||
{
|
||||
return vol_size[drive];
|
||||
return vol_size[vol];
|
||||
}
|
||||
|
||||
static bool in_volume(int drive, uint32_t sector, uint32_t count)
|
||||
static bool in_volume(int vol, uint32_t sector, uint32_t count)
|
||||
{
|
||||
return sector < vol_size[drive] && count <= vol_size[drive] - sector;
|
||||
return sector < vol_size[vol] && count <= vol_size[vol] - sector;
|
||||
}
|
||||
|
||||
static int drive_read(int drive, uint32_t sector, uint32_t count, void *buffer)
|
||||
static int vol_read(int vol, uint32_t sector, uint32_t count, void *buffer)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (in_volume(drive, sector, count))
|
||||
if (in_volume(vol, sector, count))
|
||||
{
|
||||
ret = ftl_b_read(vol_base[drive] + sector, buffer, count);
|
||||
ret = ftl_b_read(vol_base[vol] + sector, buffer, count);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef FTL_ALLOW_WRITE
|
||||
static int drive_write(int drive, uint32_t sector, uint32_t count,
|
||||
static int vol_write(int vol, uint32_t sector, uint32_t count,
|
||||
const void *buffer)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (in_volume(drive, sector, count))
|
||||
if (in_volume(vol, sector, count))
|
||||
{
|
||||
ret = ftl_b_write(vol_base[drive] + sector, buffer, count);
|
||||
ret = ftl_b_write(vol_base[vol] + sector, buffer, count);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drive_sync(void)
|
||||
static void vol_sync(void)
|
||||
{
|
||||
ftl_b_sync();
|
||||
}
|
||||
|
|
@ -305,18 +350,23 @@ uint32_t ftl_get_sectors(int drive)
|
|||
|
||||
if (drive_valid(drive))
|
||||
{
|
||||
sectors = drive_sectors(drive);
|
||||
sectors = vol_sectors(drive_volume(drive));
|
||||
}
|
||||
return sectors;
|
||||
}
|
||||
|
||||
bool ftl_drive_is_sys(int drive)
|
||||
{
|
||||
return drive_valid(drive) && drive_volume(drive) == VOL_SYS;
|
||||
}
|
||||
|
||||
uint32_t ftl_read(int drive, uint32_t sector, uint32_t count, void *buffer)
|
||||
{
|
||||
uint32_t ret = 1;
|
||||
|
||||
if (drive_valid(drive))
|
||||
{
|
||||
ret = drive_read(drive, sector, count, buffer) ? 2 : 0;
|
||||
ret = vol_read(drive_volume(drive), sector, count, buffer) ? 2 : 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -329,7 +379,7 @@ uint32_t ftl_write(int drive, uint32_t sector, uint32_t count,
|
|||
#ifdef FTL_ALLOW_WRITE
|
||||
if (drive_valid(drive))
|
||||
{
|
||||
ret = drive_write(drive, sector, count, buffer) ? 2 : 0;
|
||||
ret = vol_write(drive_volume(drive), sector, count, buffer) ? 2 : 0;
|
||||
}
|
||||
#else
|
||||
/* refuse rather than pretend: a silent success would let the filesystem
|
||||
|
|
@ -343,7 +393,7 @@ uint32_t ftl_sync(void)
|
|||
{
|
||||
if (ftl_mounted)
|
||||
{
|
||||
drive_sync();
|
||||
vol_sync();
|
||||
}
|
||||
flash_sync();
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "inttypes.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/* The drives the NAND presents: USER, and SYS only when the target exposes
|
||||
* it - see HAVE_RK27XX_NAND_SYS in the target config. */
|
||||
|
|
@ -35,6 +36,16 @@
|
|||
#define FTL_NUM_DRIVES 1
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_RK27XX_NAND_SYS) && !defined(BOOTLOADER) \
|
||||
&& defined(USB_ENABLE_STORAGE)
|
||||
/* Without SYS as a drive of its own, the debug menu can ask for it to be
|
||||
* shown to a USB host in place of USER, for one connection: the next one,
|
||||
* or the current one if none has started. Kept in RAM only. */
|
||||
#define FTL_SYS_ON_USB
|
||||
void ftl_set_sys_on_usb(bool on);
|
||||
bool ftl_get_sys_on_usb(void);
|
||||
#endif
|
||||
|
||||
uint32_t ftl_init(void);
|
||||
uint32_t ftl_read(int drive, uint32_t sector, uint32_t count, void* buffer);
|
||||
uint32_t ftl_write(int drive, uint32_t sector, uint32_t count,
|
||||
|
|
@ -45,5 +56,8 @@ uint32_t ftl_sync(void);
|
|||
* own tables, not from raw block geometry - see ftl-rk27xx.c. */
|
||||
uint32_t ftl_get_sectors(int drive);
|
||||
|
||||
/* Whether a drive shows the SYS volume right now */
|
||||
bool ftl_drive_is_sys(int drive);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue