drivers: flash_mcux_flexspi_hyperflash: move all device data to RAM

since the flexspi driver interacts with the flash device, storing
device data in flash can cause RWW hazards when running in XIP mode.
Move all device data to RAM to limit these RWW hazards.

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2022-04-27 17:32:22 -05:00 committed by David Leach
commit 836f0f5ee5

View file

@ -17,6 +17,8 @@
* called while interacting with the flexspi MUST be relocated to SRAM or ITCM
* at runtime, so that the chip does not access the flexspi to read program
* instructions while it is being written to
*
* Additionally, no data used by this driver should be stored in flash.
*/
#if defined(CONFIG_FLASH_MCUX_FLEXSPI_XIP) && (CONFIG_FLASH_LOG_LEVEL > 0)
#warning "Enabling flash driver logging and XIP mode simultaneously can cause \
@ -240,21 +242,17 @@ static const uint32_t flash_flexspi_hyperflash_lut[CUSTOM_LUT_LENGTH] = {
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10),
};
struct flash_flexspi_hyperflash_config {
flexspi_port_t port;
/* Device variables used in critical sections should be in this structure */
struct flash_flexspi_hyperflash_data {
const struct device *controller;
flexspi_device_config_t config;
flexspi_port_t port;
struct flash_pages_layout layout;
struct flash_parameters flash_parameters;
};
/* Device variables used in critical sections should be in this structure */
struct flash_flexspi_hyperflash_data {
const struct device *controller;
};
static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
flexspi_transfer_t transfer;
int ret;
@ -262,7 +260,7 @@ static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
uint32_t read_value;
transfer.deviceAddress = 0;
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Read;
transfer.SeqNumber = 2;
transfer.seqIndex = READ_STATUS;
@ -288,13 +286,12 @@ static int flash_flexspi_hyperflash_wait_bus_busy(const struct device *dev)
static int flash_flexspi_hyperflash_write_enable(const struct device *dev, uint32_t address)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
flexspi_transfer_t transfer;
int ret;
transfer.deviceAddress = address;
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Command;
transfer.SeqNumber = 2;
transfer.seqIndex = WRITE_ENABLE;
@ -306,7 +303,6 @@ static int flash_flexspi_hyperflash_write_enable(const struct device *dev, uint3
static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
uint8_t writebuf[4] = {0x00, 0x98};
uint32_t buffer[2];
@ -314,7 +310,7 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
flexspi_transfer_t transfer;
transfer.deviceAddress = (0x555 * 2);
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Write;
transfer.SeqNumber = 1;
transfer.seqIndex = WRITE_DATA;
@ -330,7 +326,7 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
}
transfer.deviceAddress = (0x10 * 2);
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Read;
transfer.SeqNumber = 1;
transfer.seqIndex = READ_DATA;
@ -351,7 +347,7 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
writebuf[1] = 0xF0;
transfer.deviceAddress = 0;
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Write;
transfer.SeqNumber = 1;
transfer.seqIndex = WRITE_DATA;
@ -372,12 +368,11 @@ static int flash_flexspi_hyperflash_check_vendor_id(const struct device *dev)
static int flash_flexspi_hyperflash_page_program(const struct device *dev, off_t
offset, const void *buffer, size_t len)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
flexspi_transfer_t transfer = {
.deviceAddress = offset,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Write,
.SeqNumber = 2,
.seqIndex = PAGE_PROGRAM,
@ -393,11 +388,10 @@ static int flash_flexspi_hyperflash_page_program(const struct device *dev, off_t
static int flash_flexspi_hyperflash_read(const struct device *dev, off_t offset,
void *buffer, size_t len)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
uint8_t *src = memc_flexspi_get_ahb_address(data->controller,
config->port,
data->port,
offset);
if (!src) {
return -EINVAL;
@ -411,7 +405,6 @@ static int flash_flexspi_hyperflash_read(const struct device *dev, off_t offset,
static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset,
const void *buffer, size_t len)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
size_t size = len;
uint8_t *src = (uint8_t *)buffer;
@ -420,7 +413,7 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset
int ret = -1;
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
config->port,
data->port,
offset);
if (!dst) {
return -EINVAL;
@ -488,7 +481,6 @@ static int flash_flexspi_hyperflash_write(const struct device *dev, off_t offset
static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset, size_t size)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
flexspi_transfer_t transfer;
int ret = -1;
@ -496,7 +488,7 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset
unsigned int key = 0;
int num_sectors = size / SPI_HYPERFLASH_SECTOR_SIZE;
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
config->port,
data->port,
offset);
if (!dst) {
@ -532,7 +524,7 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset
LOG_DBG("Erasing sector at 0x%08x", offset);
transfer.deviceAddress = offset;
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Command;
transfer.SeqNumber = 4;
transfer.seqIndex = ERASE_SECTOR;
@ -571,9 +563,9 @@ static int flash_flexspi_hyperflash_erase(const struct device *dev, off_t offset
static const struct flash_parameters *flash_flexspi_hyperflash_get_parameters(
const struct device *dev)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
return &config->flash_parameters;
return &data->flash_parameters;
}
@ -581,15 +573,14 @@ static void flash_flexspi_hyperflash_pages_layout(const struct device *dev,
const struct flash_pages_layout **layout,
size_t *layout_size)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
*layout = &config->layout;
*layout = &data->layout;
*layout_size = 1;
}
static int flash_flexspi_hyperflash_init(const struct device *dev)
{
const struct flash_flexspi_hyperflash_config *config = dev->config;
struct flash_flexspi_hyperflash_data *data = dev->data;
if (!device_is_ready(data->controller)) {
@ -599,8 +590,8 @@ static int flash_flexspi_hyperflash_init(const struct device *dev)
memc_flexspi_wait_bus_idle(data->controller);
if (memc_flexspi_set_device_config(data->controller, &config->config,
config->port)) {
if (memc_flexspi_set_device_config(data->controller, &data->config,
data->port)) {
LOG_ERR("Could not set device configuration");
return -EINVAL;
}
@ -665,10 +656,11 @@ static const struct flash_driver_api flash_flexspi_hyperflash_api = {
} \
#define FLASH_FLEXSPI_HYPERFLASH(n) \
static const struct flash_flexspi_hyperflash_config \
flash_flexspi_hyperflash_config_##n = { \
.port = DT_INST_REG_ADDR(n), \
static struct flash_flexspi_hyperflash_data \
flash_flexspi_hyperflash_data_##n = { \
.controller = DEVICE_DT_GET(DT_INST_BUS(n)), \
.config = FLASH_FLEXSPI_DEVICE_CONFIG(n), \
.port = DT_INST_REG_ADDR(n), \
.layout = { \
.pages_count = DT_INST_PROP(n, size) / 8 \
/ SPI_HYPERFLASH_SECTOR_SIZE, \
@ -680,16 +672,11 @@ static const struct flash_driver_api flash_flexspi_hyperflash_api = {
}, \
}; \
\
static struct flash_flexspi_hyperflash_data \
flash_flexspi_hyperflash_data_##n = { \
.controller = DEVICE_DT_GET(DT_INST_BUS(n)), \
}; \
\
DEVICE_DT_INST_DEFINE(n, \
flash_flexspi_hyperflash_init, \
NULL, \
&flash_flexspi_hyperflash_data_##n, \
&flash_flexspi_hyperflash_config_##n, \
NULL, \
POST_KERNEL, \
CONFIG_FLASH_INIT_PRIORITY, \
&flash_flexspi_hyperflash_api);