Skip to content

Commit

Permalink
storage: implement generic extensible flash driver
Browse files Browse the repository at this point in the history
JIRA: RTOS-951
  • Loading branch information
lukileczo committed Jan 21, 2025
1 parent 0a22767 commit 88f5d33
Show file tree
Hide file tree
Showing 27 changed files with 1,644 additions and 327 deletions.
2 changes: 1 addition & 1 deletion _targets/Makefile.riscv64-noelv
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
# Copyright 2024 Phoenix Systems
#

DEFAULT_COMPONENTS := grlib-uart
DEFAULT_COMPONENTS := grlib-uart flashdrv
4 changes: 2 additions & 2 deletions _targets/Makefile.sparcv8leon-gr740
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# sparcv8leon-gr740 drivers
#
# Copyright 2024 Phoenix Systems
# Copyright 2025 Phoenix Systems
#

DEFAULT_COMPONENTS := grlib-multi ftmctrl-flash
DEFAULT_COMPONENTS := grlib-multi flashdrv
12 changes: 12 additions & 0 deletions storage/flashdrv/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Makefile for Phoenix-RTOS ftmctrl-flash driver
#
# Copyright 2023-2025 Phoenix Systems
#

NAME := flashdrv
LOCAL_SRCS := common.c flashsrv.c
DEP_LIBS := libftmctrl libspimctrl
LIBS := libjffs2 libstorage libmtd libptable libcache

include $(binary.mk)
28 changes: 28 additions & 0 deletions storage/flashdrv/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Phoenix-RTOS
*
* GRLIB FTMCTRL Flash driver
*
* Common auxiliary functions
*
* Copyright 2025 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <flashdrv/common.h>


off_t common_getSectorOffset(size_t sectorsz, off_t offs)
{
return offs & ~(sectorsz - 1);
}


bool common_isValidAddress(size_t memsz, off_t offs, size_t len)
{
return ((offs < memsz) && ((offs + len) <= memsz));
}
10 changes: 10 additions & 0 deletions storage/flashdrv/drv/grlib-ftmctrl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Makefile for Phoenix-RTOS libftmctrl driver
#
# Copyright 2025 Phoenix Systems
#

NAME := libftmctrl
LOCAL_SRCS := amd-flash.c flashdrv.c flash.c intel-flash.c

include $(static-lib.mk)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* AMD command set flash interface
*
* Copyright 2024 Phoenix Systems
* Copyright 2025 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
Expand Down Expand Up @@ -115,7 +115,7 @@ static void amd_exitQuery(volatile uint8_t *base)
}


void amd_register(void)
void ftmctrl_amd_register(void)
{
static const flash_ops_t ops = {
.statusRead = amd_statusRead,
Expand Down Expand Up @@ -143,6 +143,6 @@ void amd_register(void)
};

for (size_t i = 0; i < (sizeof(amd_devices) / sizeof(amd_devices[0])); ++i) {
flash_register(&amd_devices[i]);
ftmctrl_flash_register(&amd_devices[i]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
*
* Flash commands
*
* Copyright 2024 Phoenix Systems
* Copyright 2025 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#ifndef _CMDS_H_
#define _CMDS_H_
#ifndef _FTMCTRL_CMDS_H_
#define _FTMCTRL_CMDS_H_


/* Common flash commands */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* GRLIB FTMCTRL Flash driver
*
* Copyright 2023, 2024 Phoenix Systems
* Copyright 2023-2025 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
Expand All @@ -22,6 +22,8 @@
#include <sys/mman.h>
#include <sys/time.h>

#include <flashdrv/common.h>

#include "cmds.h"
#include "flash.h"
#include "flashdrv.h"
Expand Down Expand Up @@ -111,7 +113,7 @@ static uint16_t flash_deserialize16(uint16_t value)
}


int flash_writeBuffer(const struct _storage_devCtx_t *ctx, off_t offs, const uint8_t *data, size_t len, time_t timeout)
int ftmctrl_flash_writeBuffer(const struct _storage_devCtx_t *ctx, off_t offs, const uint8_t *data, size_t len, time_t timeout)
{
uint16_t val;
const int portWidth = ftmctrl_portWidth(ctx->ftmctrl);
Expand Down Expand Up @@ -139,10 +141,10 @@ int flash_writeBuffer(const struct _storage_devCtx_t *ctx, off_t offs, const uin
data += i;

if (len == 0) {
return EOK;
return 0;
}

off_t sectorOffs = flash_getSectorOffset(ctx, offs);
off_t sectorOffs = common_getSectorOffset(ctx->sectorsz, offs);

ctx->dev->ops->issueWriteBuffer(common.base, sectorOffs, offs, len);

Expand Down Expand Up @@ -196,7 +198,7 @@ int flash_writeBuffer(const struct _storage_devCtx_t *ctx, off_t offs, const uin
}


int flash_sectorErase(const struct _storage_devCtx_t *ctx, off_t sectorOffs, time_t timeout)
int ftmctrl_flash_sectorErase(const struct _storage_devCtx_t *ctx, off_t sectorOffs, time_t timeout)
{
ctx->dev->ops->issueSectorErase(common.base, sectorOffs);

Expand Down Expand Up @@ -230,7 +232,7 @@ int flash_sectorErase(const struct _storage_devCtx_t *ctx, off_t sectorOffs, tim
}


int flash_chipErase(const struct _storage_devCtx_t *ctx, time_t timeout)
int ftmctrl_flash_chipErase(const struct _storage_devCtx_t *ctx, time_t timeout)
{
if (ctx->dev->ops->issueChipErase == NULL) {
return -ENOSYS;
Expand All @@ -248,15 +250,15 @@ int flash_chipErase(const struct _storage_devCtx_t *ctx, time_t timeout)
}


void flash_read(const struct _storage_devCtx_t *ctx, off_t offs, void *buff, size_t len)
void ftmctrl_flash_read(const struct _storage_devCtx_t *ctx, off_t offs, void *buff, size_t len)
{
ctx->dev->ops->issueReset(common.base);

memcpy(buff, (void *)(common.base + offs), len);
}


void flash_printInfo(const struct _storage_devCtx_t *ctx)
void ftmctrl_flash_printInfo(const struct _storage_devCtx_t *ctx)
{
LOG("configured %s %u MB flash", ctx->dev->name, CFI_SIZE(ctx->cfi.chipSz) / (1024 * 1024));
}
Expand Down Expand Up @@ -331,13 +333,13 @@ static const flash_dev_t *flash_query(cfi_info_t *cfi)
}


int flash_init(struct _storage_devCtx_t *ctx)
int ftmctrl_flash_init(struct _storage_devCtx_t *ctx, addr_t flashBase)
{
amd_register();
intel_register();
ftmctrl_amd_register();
ftmctrl_intel_register();

/* Temporarily map one page on flash as uncached to be able to read status */
common.base = mmap(NULL, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_DEVICE | MAP_PHYSMEM | MAP_ANONYMOUS, -1, ADDR_FLASH);
common.base = mmap(NULL, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_DEVICE | MAP_PHYSMEM | MAP_ANONYMOUS, -1, flashBase);
if (common.base == MAP_FAILED) {
LOG_ERROR("failed to map flash");
return -ENOMEM;
Expand All @@ -356,21 +358,28 @@ int flash_init(struct _storage_devCtx_t *ctx)
ctx->sectorsz = CFI_SIZE(ctx->cfi.chipSz) / (ctx->cfi.regions[0].count + 1);

/* Map entire flash */
common.base = mmap(NULL, CFI_SIZE(ctx->cfi.chipSz), PROT_READ | PROT_WRITE, MAP_DEVICE | MAP_PHYSMEM | MAP_ANONYMOUS, -1, ADDR_FLASH);
common.base = mmap(NULL, CFI_SIZE(ctx->cfi.chipSz), PROT_READ | PROT_WRITE, MAP_DEVICE | MAP_PHYSMEM | MAP_ANONYMOUS, -1, flashBase);
if (common.base == MAP_FAILED) {
LOG_ERROR("failed to map flash");
return -ENOMEM;
}

return EOK;
return 0;
}


void ftmctrl_flash_destroy(struct _storage_devCtx_t *ctx)
{
(void)munmap((void *)common.base, CFI_SIZE(ctx->cfi.chipSz));
}


void flash_register(const flash_dev_t *dev)
void ftmctrl_flash_register(const flash_dev_t *dev)
{
if (common.nmodels >= FLASH_DEVICES) {
LOG("Too many flashes: %s not registered. Please increase FLASH_DEVICES", dev->name);
return;
}
common.devs[common.nmodels++] = dev;
else {
common.devs[common.nmodels++] = dev;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
*
* Internal flash functions
*
* Copyright 2023, 2024 Phoenix Systems
* Copyright 2023-2025 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#ifndef _FLASH_H_
#define _FLASH_H_
#ifndef _FTMCTRL_FLASH_H_
#define _FTMCTRL_FLASH_H_


#include <sys/types.h>
Expand Down Expand Up @@ -47,37 +47,34 @@ typedef struct _flash_dev_t {
} flash_dev_t;


static inline off_t flash_getSectorOffset(const struct _storage_devCtx_t *ctx, off_t offs)
{
return offs & ~(ctx->sectorsz - 1);
}
int ftmctrl_flash_writeBuffer(const struct _storage_devCtx_t *ctx, off_t offs, const uint8_t *data, size_t len, time_t timeout);

/* Timeout in us */
int ftmctrl_flash_sectorErase(const struct _storage_devCtx_t *ctx, off_t sectorOffs, time_t timeout);

int flash_writeBuffer(const struct _storage_devCtx_t *ctx, off_t offs, const uint8_t *data, size_t len, time_t timeout);

/* Timeout in us */
int flash_sectorErase(const struct _storage_devCtx_t *ctx, off_t sectorOffs, time_t timeout);
int ftmctrl_flash_chipErase(const struct _storage_devCtx_t *ctx, time_t timeout);


int flash_chipErase(const struct _storage_devCtx_t *ctx, time_t timeout);
void ftmctrl_flash_read(const struct _storage_devCtx_t *ctx, off_t offs, void *buff, size_t len);


void flash_read(const struct _storage_devCtx_t *ctx, off_t offs, void *buff, size_t len);
void ftmctrl_flash_printInfo(const struct _storage_devCtx_t *ctx);


void flash_printInfo(const struct _storage_devCtx_t *ctx);
int ftmctrl_flash_init(struct _storage_devCtx_t *ctx, addr_t flashBase);


int flash_init(struct _storage_devCtx_t *ctx);
void ftmctrl_flash_destroy(struct _storage_devCtx_t *ctx);


void flash_register(const flash_dev_t *dev);
void ftmctrl_flash_register(const flash_dev_t *dev);


void amd_register(void);
void ftmctrl_amd_register(void);


void intel_register(void);
void ftmctrl_intel_register(void);


#endif
Loading

0 comments on commit 88f5d33

Please sign in to comment.