drivers: flash_mcux_flexspi_mx25um51345g: 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:42:11 -05:00 committed by David Leach
commit e8f7181c50

View file

@ -28,6 +28,8 @@ static uint8_t nor_write_buf[SPI_NOR_PAGE_SIZE];
* 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 \
@ -50,16 +52,13 @@ enum {
ERASE_CHIP,
};
struct flash_flexspi_nor_config {
flexspi_port_t port;
flexspi_device_config_t config;
struct flash_pages_layout layout;
struct flash_parameters flash_parameters;
};
/* Device variables used in critical sections should be in this structure */
struct flash_flexspi_nor_data {
const struct device *controller;
flexspi_device_config_t config;
flexspi_port_t port;
struct flash_pages_layout layout;
struct flash_parameters flash_parameters;
};
static const uint32_t flash_flexspi_nor_lut[][4] = {
@ -131,14 +130,13 @@ static const uint32_t flash_flexspi_nor_lut[][4] = {
static int flash_flexspi_nor_get_vendor_id(const struct device *dev,
uint8_t *vendor_id)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
uint32_t buffer = 0;
int ret;
flexspi_transfer_t transfer = {
.deviceAddress = 0,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Read,
.SeqNumber = 1,
.seqIndex = READ_ID_OPI,
@ -157,12 +155,11 @@ static int flash_flexspi_nor_get_vendor_id(const struct device *dev,
static int flash_flexspi_nor_read_status(const struct device *dev,
uint32_t *status)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
flexspi_transfer_t transfer = {
.deviceAddress = 0,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Read,
.SeqNumber = 1,
.seqIndex = READ_STATUS_REG,
@ -178,12 +175,11 @@ static int flash_flexspi_nor_read_status(const struct device *dev,
static int flash_flexspi_nor_write_status(const struct device *dev,
uint32_t *status)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
flexspi_transfer_t transfer = {
.deviceAddress = 0,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Write,
.SeqNumber = 1,
.seqIndex = ENTER_OPI,
@ -199,12 +195,11 @@ static int flash_flexspi_nor_write_status(const struct device *dev,
static int flash_flexspi_nor_write_enable(const struct device *dev,
bool enableOctal)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
flexspi_transfer_t transfer;
transfer.deviceAddress = 0;
transfer.port = config->port;
transfer.port = data->port;
transfer.cmdType = kFLEXSPI_Command;
transfer.SeqNumber = 1;
if (enableOctal) {
@ -223,12 +218,11 @@ static int flash_flexspi_nor_write_enable(const struct device *dev,
static int flash_flexspi_nor_erase_sector(const struct device *dev,
off_t offset)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
flexspi_transfer_t transfer = {
.deviceAddress = offset,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Command,
.SeqNumber = 1,
.seqIndex = ERASE_SECTOR,
@ -243,12 +237,11 @@ static int flash_flexspi_nor_erase_sector(const struct device *dev,
static int flash_flexspi_nor_erase_chip(const struct device *dev)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
flexspi_transfer_t transfer = {
.deviceAddress = 0,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Command,
.SeqNumber = 1,
.seqIndex = ERASE_CHIP,
@ -264,12 +257,11 @@ static int flash_flexspi_nor_erase_chip(const struct device *dev)
static int flash_flexspi_nor_page_program(const struct device *dev,
off_t offset, const void *buffer, size_t len)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
flexspi_transfer_t transfer = {
.deviceAddress = offset,
.port = config->port,
.port = data->port,
.cmdType = kFLEXSPI_Write,
.SeqNumber = 1,
.seqIndex = PAGE_PROGRAM,
@ -316,10 +308,9 @@ static int flash_flexspi_enable_octal_mode(const struct device *dev)
static int flash_flexspi_nor_read(const struct device *dev, off_t offset,
void *buffer, size_t len)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
uint8_t *src = memc_flexspi_get_ahb_address(data->controller,
config->port,
data->port,
offset);
memcpy(buffer, src, len);
@ -330,7 +321,6 @@ static int flash_flexspi_nor_read(const struct device *dev, off_t offset,
static int flash_flexspi_nor_write(const struct device *dev, off_t offset,
const void *buffer, size_t len)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
size_t size = len;
uint8_t *src = (uint8_t *) buffer;
@ -338,7 +328,7 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset,
unsigned int key = 0;
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
config->port,
data->port,
offset);
if (memc_flexspi_is_running_xip(data->controller)) {
@ -387,14 +377,13 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset,
static int flash_flexspi_nor_erase(const struct device *dev, off_t offset,
size_t size)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
int num_sectors = size / SPI_NOR_SECTOR_SIZE;
int i;
unsigned int key = 0;
uint8_t *dst = memc_flexspi_get_ahb_address(data->controller,
config->port,
data->port,
offset);
if (offset % SPI_NOR_SECTOR_SIZE) {
@ -416,7 +405,7 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset,
key = irq_lock();
}
if ((offset == 0) && (size == config->config.flashSize * KB(1))) {
if ((offset == 0) && (size == data->config.flashSize * KB(1))) {
flash_flexspi_nor_write_enable(dev, true);
flash_flexspi_nor_erase_chip(dev);
flash_flexspi_nor_wait_bus_busy(dev);
@ -446,25 +435,24 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset,
static const struct flash_parameters *flash_flexspi_nor_get_parameters(
const struct device *dev)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
return &config->flash_parameters;
return &data->flash_parameters;
}
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
static void flash_flexspi_nor_pages_layout(const struct device *dev,
const struct flash_pages_layout **layout, size_t *layout_size)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
*layout = &config->layout;
*layout = &data->layout;
*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static int flash_flexspi_nor_init(const struct device *dev)
{
const struct flash_flexspi_nor_config *config = dev->config;
struct flash_flexspi_nor_data *data = dev->data;
uint8_t vendor_id;
@ -474,8 +462,8 @@ static int flash_flexspi_nor_init(const struct device *dev)
}
if (!memc_flexspi_is_running_xip(data->controller) &&
memc_flexspi_set_device_config(data->controller, &config->config,
config->port)) {
memc_flexspi_set_device_config(data->controller, &data->config,
data->port)) {
LOG_ERR("Could not set device configuration");
return -EINVAL;
}
@ -546,10 +534,11 @@ static const struct flash_driver_api flash_flexspi_nor_api = {
} \
#define FLASH_FLEXSPI_NOR(n) \
static const struct flash_flexspi_nor_config \
flash_flexspi_nor_config_##n = { \
.port = DT_INST_REG_ADDR(n), \
static struct flash_flexspi_nor_data \
flash_flexspi_nor_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_NOR_SECTOR_SIZE, \
@ -561,16 +550,11 @@ static const struct flash_driver_api flash_flexspi_nor_api = {
}, \
}; \
\
static struct flash_flexspi_nor_data \
flash_flexspi_nor_data_##n = { \
.controller = DEVICE_DT_GET(DT_INST_BUS(n)), \
}; \
\
DEVICE_DT_INST_DEFINE(n, \
flash_flexspi_nor_init, \
NULL, \
&flash_flexspi_nor_data_##n, \
&flash_flexspi_nor_config_##n, \
NULL, \
POST_KERNEL, \
CONFIG_FLASH_INIT_PRIORITY, \
&flash_flexspi_nor_api);