Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: mbox: mbox_esp32: fix mbox callback call #78517

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 41 additions & 53 deletions drivers/mbox/mbox_esp32.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
LOG_MODULE_REGISTER(mbox_esp32, CONFIG_MBOX_LOG_LEVEL);

#define ESP32_MBOX_LOCK_FREE_VAL 0xB33FFFFF
#define ESP32_MBOX_NOOP_VAL 0xFF
#define ESP32_MBOX_NOOP_VAL 0xFF

__packed struct esp32_mbox_control {
uint16_t dest_cpu_msg_id[2];
Expand Down Expand Up @@ -50,6 +50,7 @@ struct esp32_mbox_data {
IRAM_ATTR static void esp32_mbox_isr(const struct device *dev)
{
struct esp32_mbox_data *dev_data = (struct esp32_mbox_data *)dev->data;
struct mbox_msg msg;
uint32_t core_id = dev_data->this_core_id;

/* clear interrupt flag */
Expand All @@ -68,25 +69,27 @@ IRAM_ATTR static void esp32_mbox_isr(const struct device *dev)
}

/* first of all take the ownership of the shared memory */
while (!atomic_cas(&dev_data->control->lock,
ESP32_MBOX_LOCK_FREE_VAL, dev_data->this_core_id))
while (!atomic_cas(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
dev_data->this_core_id))
;

if (dev_data->cb) {
/* For ESP32 soft mbox driver, the message parameter of the callback holds
* the portion of shared memory that belongs to the current core ID.
*/
msg.data = (dev_data->this_core_id == 0) ? (const void *)dev_data->shm.pro_cpu_shm
: (const void *)dev_data->shm.app_cpu_shm;
msg.size = dev_data->shm_size;

volatile void *shm = dev_data->shm.pro_cpu_shm;

if (core_id != 0) {
shm = dev_data->shm.app_cpu_shm;
}
dev_data->cb(dev, dev_data->other_core_id, dev_data->user_data, &msg);
}

/* unlock the shared memory */
atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
}

static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
const struct mbox_msg *msg)
const struct mbox_msg *msg)
{
ARG_UNUSED(msg);

Expand All @@ -100,9 +103,8 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
uint32_t key = irq_lock();

/* try to lock the shared memory */
while (!atomic_cas(&dev_data->control->lock,
ESP32_MBOX_LOCK_FREE_VAL,
dev_data->this_core_id)) {
while (!atomic_cas(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
dev_data->this_core_id)) {
k_msleep(1);
}

Expand Down Expand Up @@ -135,7 +137,7 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
}

static int esp32_mbox_register_callback(const struct device *dev, mbox_channel_id_t channel,
mbox_callback_t cb, void *user_data)
mbox_callback_t cb, void *user_data)
{
ARG_UNUSED(channel);

Expand Down Expand Up @@ -183,14 +185,13 @@ static int esp32_mbox_set_enabled(const struct device *dev, mbox_channel_id_t ch
return 0;
}


static int esp32_mbox_init(const struct device *dev)
{
struct esp32_mbox_data *data = (struct esp32_mbox_data *)dev->data;
struct esp32_mbox_config *cfg = (struct esp32_mbox_config *)dev->config;

data->this_core_id = esp_core_id();
data->other_core_id = (data->this_core_id == 0) ? 1 : 0;
data->other_core_id = (data->this_core_id == 0) ? 1 : 0;

LOG_DBG("Size of MBOX shared memory: %d", data->shm_size);
LOG_DBG("Address of PRO_CPU MBOX shared memory: %p", data->shm.pro_cpu_shm);
Expand All @@ -199,32 +200,25 @@ static int esp32_mbox_init(const struct device *dev)

/* pro_cpu is responsible to initialize the lock of shared memory */
if (data->this_core_id == 0) {
esp_intr_alloc(cfg->irq_source_pro_cpu,
ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr,
(void *)dev,
NULL);
esp_intr_alloc(cfg->irq_source_pro_cpu, ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr, (void *)dev, NULL);

atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
} else {
/* app_cpu wait for initialization from pro_cpu, then takes it,
* after that releases
*/
esp_intr_alloc(cfg->irq_source_app_cpu,
ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr,
(void *)dev,
NULL);
esp_intr_alloc(cfg->irq_source_app_cpu, ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr, (void *)dev, NULL);

LOG_DBG("Waiting CPU0 to sync");
while (!atomic_cas(&data->control->lock,
ESP32_MBOX_LOCK_FREE_VAL, data->this_core_id))
while (!atomic_cas(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
data->this_core_id))
;

atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);

LOG_DBG("Synchronization done");

}

return 0;
Expand All @@ -238,30 +232,24 @@ static const struct mbox_driver_api esp32_mbox_driver_api = {
.set_enabled = esp32_mbox_set_enabled,
};

#define ESP32_MBOX_SHM_SIZE_BY_IDX(idx) \
DT_INST_PROP(idx, shared_memory_size) \

#define ESP32_MBOX_SHM_ADDR_BY_IDX(idx) \
DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(idx), shared_memory)) \

#define ESP32_MBOX_INIT(idx) \
\
static struct esp32_mbox_config esp32_mbox_device_cfg_##idx = { \
.irq_source_pro_cpu = DT_INST_IRQN(idx), \
.irq_source_app_cpu = DT_INST_IRQN(idx) + 1, \
}; \
\
static struct esp32_mbox_data esp32_mbox_device_data_##idx = { \
.shm_size = ESP32_MBOX_SHM_SIZE_BY_IDX(idx), \
.shm.pro_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx), \
.shm.app_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx) + \
ESP32_MBOX_SHM_SIZE_BY_IDX(idx)/2, \
.control = (struct esp32_mbox_control *)DT_INST_REG_ADDR(idx), \
}; \
\
DEVICE_DT_INST_DEFINE(idx, &esp32_mbox_init, NULL, \
&esp32_mbox_device_data_##idx, &esp32_mbox_device_cfg_##idx, \
PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&esp32_mbox_driver_api); \
#define ESP32_MBOX_SHM_SIZE_BY_IDX(idx) DT_INST_PROP(idx, shared_memory_size)

#define ESP32_MBOX_SHM_ADDR_BY_IDX(idx) DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(idx), shared_memory))

#define ESP32_MBOX_INIT(idx) \
static struct esp32_mbox_config esp32_mbox_device_cfg_##idx = { \
.irq_source_pro_cpu = DT_INST_IRQN(idx), \
.irq_source_app_cpu = DT_INST_IRQN(idx) + 1, \
}; \
static struct esp32_mbox_data esp32_mbox_device_data_##idx = { \
.shm_size = ESP32_MBOX_SHM_SIZE_BY_IDX(idx), \
.shm.pro_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx), \
.shm.app_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx) + \
ESP32_MBOX_SHM_SIZE_BY_IDX(idx) / 2, \
.control = (struct esp32_mbox_control *)DT_INST_REG_ADDR(idx), \
}; \
DEVICE_DT_INST_DEFINE(idx, &esp32_mbox_init, NULL, &esp32_mbox_device_data_##idx, \
&esp32_mbox_device_cfg_##idx, PRE_KERNEL_2, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &esp32_mbox_driver_api);

DT_INST_FOREACH_STATUS_OKAY(ESP32_MBOX_INIT);
Loading