Skip to content
Snippets Groups Projects
Commit 01dab506 authored by schneider's avatar schneider
Browse files

Merge branch 'rahix/no-irq-epic-calls' into 'master'

Disable core 1 interrupts during API calls

See merge request !474
parents d125e331 92741109
Branches
Tags
1 merge request!474Disable core 1 interrupts during API calls
Pipeline #5225 passed
...@@ -5,8 +5,17 @@ ...@@ -5,8 +5,17 @@
#define MXC_ASSERT_ENABLE #define MXC_ASSERT_ENABLE
#include "mxc_assert.h" #include "mxc_assert.h"
static uint32_t irq_save = 0;
void *_api_call_start(api_id_t id, uintptr_t size) void *_api_call_start(api_id_t id, uintptr_t size)
{ {
/*
* Disable all maskable interrupts here, to be turned on again at the
* end of _api_call_transact().
*/
irq_save = __get_PRIMASK();
__set_PRIMASK(1);
while (SEMA_GetSema(_API_SEMAPHORE) == E_BUSY) { while (SEMA_GetSema(_API_SEMAPHORE) == E_BUSY) {
} }
...@@ -51,6 +60,12 @@ void *_api_call_transact(void *buffer) ...@@ -51,6 +60,12 @@ void *_api_call_transact(void *buffer)
API_CALL_MEM->call_flag = _API_FLAG_IDLE; API_CALL_MEM->call_flag = _API_FLAG_IDLE;
SEMA_FreeSema(_API_SEMAPHORE); SEMA_FreeSema(_API_SEMAPHORE);
/*
* Re-enable interrupts (if previously enabled) after completing the API
* call.
*/
__set_PRIMASK(irq_save);
return API_CALL_MEM->buffer; return API_CALL_MEM->buffer;
} }
......
...@@ -214,10 +214,10 @@ void core1_trigger_reset(void) ...@@ -214,10 +214,10 @@ void core1_trigger_reset(void)
interrupt_trigger_sync(EPIC_INT_RESET); interrupt_trigger_sync(EPIC_INT_RESET);
} }
void core1_wait_ready(void) bool core1_is_ready(void)
{ {
/* Wait for the core to accept */ bool ready;
while (1) {
while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) { while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) {
} }
...@@ -225,12 +225,20 @@ void core1_wait_ready(void) ...@@ -225,12 +225,20 @@ void core1_wait_ready(void)
* core 1 will set the ready flag once it is spinning in the * core 1 will set the ready flag once it is spinning in the
* above loop, waiting for a new IVT. * above loop, waiting for a new IVT.
*/ */
if (core1_info.ready) { ready = core1_info.ready;
SEMA_FreeSema(_CONTROL_SEMAPHORE); SEMA_FreeSema(_CONTROL_SEMAPHORE);
break;
return ready;
} }
SEMA_FreeSema(_CONTROL_SEMAPHORE); void core1_wait_ready(void)
{
/* Wait for the core to accept */
while (1) {
if (core1_is_ready()) {
break;
}
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {
} }
......
...@@ -39,6 +39,9 @@ void core1_boot(void); ...@@ -39,6 +39,9 @@ void core1_boot(void);
/* Reset core 1 into a state where it can accept a new payload */ /* Reset core 1 into a state where it can accept a new payload */
void core1_trigger_reset(void); void core1_trigger_reset(void);
/* Check if core 1 is ready for a new payload */
bool core1_is_ready(void);
/* Wait for core 1 to respond that it is ready for a new payload */ /* Wait for core 1 to respond that it is ready for a new payload */
void core1_wait_ready(void); void core1_wait_ready(void);
......
...@@ -119,8 +119,18 @@ static int do_load(struct load_info *info) ...@@ -119,8 +119,18 @@ static int do_load(struct load_info *info)
/* /*
* Wait for the core to become ready to accept a new payload. * Wait for the core to become ready to accept a new payload.
*
* If it is not yet ready, hand back control of the API mutex to the
* dispatcher so it can finish dispatching a current API call. This is
* necessary for payloads which have interrupts disabled during an API
* call.
*/ */
core1_wait_ready(); while (!core1_is_ready()) {
mutex_unlock(&api_mutex);
/* Sleep so the dispatcher task can take the lock. */
vTaskDelay(8);
mutex_lock(&api_mutex);
}
/* /*
* Reinitialize Hardware & Drivers * Reinitialize Hardware & Drivers
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment