From b2a364766314a828b941e81ece82c6badbb3b943 Mon Sep 17 00:00:00 2001 From: Gerard Swiderski Date: Wed, 26 Jun 2024 06:56:38 +0200 Subject: [PATCH] cmds/ptable: use io control to get device props Adds io control to get total size and block size of flash device. JIRA: RTOS-848 --- cmds/ptable.c | 38 ++++++++++++++++++++++++++++------ devices/devs.h | 5 ++++- devices/flash-imxrt/flashdrv.c | 25 ++++++++++++++++++++++ phfs/phfs.c | 32 +++++++++++++++++++++++++--- phfs/phfs.h | 9 ++++++++ 5 files changed, 99 insertions(+), 10 deletions(-) diff --git a/cmds/ptable.c b/cmds/ptable.c index 33f9080f..a84d3842 100644 --- a/cmds/ptable.c +++ b/cmds/ptable.c @@ -29,9 +29,9 @@ static struct { - u32 memsz; - u32 blksz; ptable_t ptable[1024]; + size_t memsz; + size_t blksz; } ptable_common; @@ -109,16 +109,16 @@ static int cmd_ptable(int argc, char *argv[]) char *endptr = NULL; handler_t h; - /* FIXME: add info to phfs */ - ptable_common.memsz = 32 * 1024 * 1024; - ptable_common.blksz = 4096; + unsigned int major; + unsigned int minor; + unsigned int prot; if ((argc != 2) && (argc != 3)) { log_error("\n%s: Wrong argument count", argv[0]); return -EINVAL; } - if (argc > 2) { + if (argc == 3) { offs = lib_strtoul(argv[2], &endptr, 0); if (argv[2] == endptr) { log_error("\n%s: Wrong arguments", argv[0]); @@ -126,6 +126,30 @@ static int cmd_ptable(int argc, char *argv[]) } } + if (phfs_devGet(argv[1], &major, &minor, &prot) != EOK) { + lib_printf("\n%s: Invalid phfs name provided: %s\n", argv[0], argv[1]); + return CMD_EXIT_FAILURE; + } + + if (prot != phfs_prot_raw) { + lib_printf("\n%s: Device %s does not use raw protocol\n", argv[0], argv[1]); + return CMD_EXIT_FAILURE; + } + + if ((devs_control(major, minor, DEV_CONTROL_GETPROP_TOTALSZ, &ptable_common.memsz) != EOK) || + (devs_control(major, minor, DEV_CONTROL_GETPROP_BLOCKSZ, &ptable_common.blksz) != EOK)) { + lib_printf("\n%s: Unable to get %s device properties: %s\n", argv[0], argv[1]); + return CMD_EXIT_FAILURE; + } + + if (argc != 3) { + /* by default ptable is located in the last sector of raw device */ + offs = ptable_common.memsz - ptable_common.blksz; + } + + lib_printf("\nDevice size: %zu", ptable_common.memsz); + lib_printf("\nBlock size: %zu\n", ptable_common.blksz); + if (phfs_open(argv[1], NULL, PHFS_OPEN_RAWONLY, &h) < 0) { lib_printf("\n%s: Invalid phfs name provided: %s\n", argv[0], argv[1]); return CMD_EXIT_FAILURE; @@ -136,11 +160,13 @@ static int cmd_ptable(int argc, char *argv[]) (void)phfs_close(h); if (res <= 0) { + log_error("\n%s: Missing partition table at offset %zu", argv[0], offs); return CMD_EXIT_FAILURE; } if (res > 0) { partPrint(ptable_common.ptable); + lib_printf("\nPartition table at offset: %zu\n", offs); } return CMD_EXIT_SUCCESS; diff --git a/devices/devs.h b/devices/devs.h index dfc61a1d..216ab4b4 100644 --- a/devices/devs.h +++ b/devices/devs.h @@ -30,7 +30,10 @@ #define DEVS_ITER_STOP ((const dev_t *)-1) -#define DEV_CONTROL_SETBAUD 1 +#define DEV_CONTROL_SETBAUD 1 +#define DEV_CONTROL_GETBAUD 2 +#define DEV_CONTROL_GETPROP_TOTALSZ 3 +#define DEV_CONTROL_GETPROP_BLOCKSZ 4 /* clang-format off */ enum { dev_isMappable = 0, dev_isNotMappable }; diff --git a/devices/flash-imxrt/flashdrv.c b/devices/flash-imxrt/flashdrv.c index 4d2fb7d5..07168438 100644 --- a/devices/flash-imxrt/flashdrv.c +++ b/devices/flash-imxrt/flashdrv.c @@ -88,6 +88,30 @@ static inline addr_t get_sectorAddress(struct nor_device *dev, addr_t addr) /* Device driver interface */ +static int flashdrv_control(unsigned int minor, int cmd, void *args) +{ + struct nor_device *dev = minorToDevice(minor); + size_t *outSz = args; + + if (dev == NULL || dev->active == 0) { + return -ENXIO; + } + + switch (cmd) { + case DEV_CONTROL_GETPROP_TOTALSZ: + *outSz = dev->fspi.slFlashSz[dev->port]; + return EOK; + + case DEV_CONTROL_GETPROP_BLOCKSZ: + *outSz = dev->nor->sectorSz; /* FIXME: assumed uniform sector */ + return EOK; + + default: + break; + } + + return -ENOSYS; +} static int flashdrv_map(unsigned int minor, addr_t addr, size_t sz, int mode, addr_t memaddr, size_t memsz, int memmode, addr_t *a) { @@ -463,6 +487,7 @@ __attribute__((constructor)) static void flashdrv_reg(void) .erase = flashdrv_erase, .sync = flashdrv_sync, .map = flashdrv_map, + .control = flashdrv_control, }; static const dev_t devFlashIMXRT = { diff --git a/phfs/phfs.c b/phfs/phfs.c index 1f142418..e27c6af9 100644 --- a/phfs/phfs.c +++ b/phfs/phfs.c @@ -24,9 +24,6 @@ #define PHFS_TIMEOUT_MS 500 -enum { phfs_prot_raw = 0, phfs_prot_phoenixd }; - - typedef struct { char alias[8]; unsigned int major; @@ -138,6 +135,35 @@ int phfs_devReg(const char *alias, unsigned int major, unsigned int minor, const } +int phfs_devGet(const char *alias, unsigned int *retMajor, unsigned int *retMinor, unsigned int *retProt) +{ + phfs_device_t *pd; + int i; + + if (phfs_common.dCnt == 0) { + return -ENODEV; + } + + for (i = 0; i < phfs_common.dCnt; ++i) { + pd = &phfs_common.devices[i]; + if (hal_strcmp(pd->alias, alias) == 0) { + if (retMajor != NULL) { + *retMajor = pd->major; + } + if (retMinor != NULL) { + *retMinor = pd->minor; + } + if (retProt != NULL) { + *retProt = pd->prot; + } + return EOK; + } + } + + return -ENODEV; +} + + int phfs_aliasAddrResolve(handler_t h, addr_t *addr) { if (h.id >= SIZE_PHFS_ALIASES || h.id >= phfs_common.fCnt) diff --git a/phfs/phfs.h b/phfs/phfs.h index 5d487dfe..f5aeb3b7 100644 --- a/phfs/phfs.h +++ b/phfs/phfs.h @@ -26,6 +26,11 @@ #define PHFS_OPEN_RAWONLY 0x80000000 +/* clang-format off */ +enum { phfs_prot_raw = 0, phfs_prot_phoenixd }; +/* clang-format on */ + + typedef struct { unsigned int pd; /* phfs device descriptor */ unsigned int id; /* file id */ @@ -47,6 +52,10 @@ extern int phfs_devReg(const char *alias, unsigned int major, unsigned int minor extern int phfs_aliasReg(const char *alias, addr_t addr, size_t size); +/* Get minor, major and protocol of the registered device alias */ +int phfs_devGet(const char *alias, unsigned int *retMajor, unsigned int *retMinor, unsigned int *retProt); + + /* Get file's address based on the given handler */ extern int phfs_aliasAddrResolve(handler_t h, addr_t *addr);