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
Pipeline #5225 passed with stages
in 2 minutes and 18 seconds
......@@ -5,8 +5,17 @@
#define MXC_ASSERT_ENABLE
#include "mxc_assert.h"
static uint32_t irq_save = 0;
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) {
}
......@@ -51,6 +60,12 @@ void *_api_call_transact(void *buffer)
API_CALL_MEM->call_flag = _API_FLAG_IDLE;
SEMA_FreeSema(_API_SEMAPHORE);
/*
* Re-enable interrupts (if previously enabled) after completing the API
* call.
*/
__set_PRIMASK(irq_save);
return API_CALL_MEM->buffer;
}
......
......@@ -214,24 +214,32 @@ void core1_trigger_reset(void)
interrupt_trigger_sync(EPIC_INT_RESET);
}
bool core1_is_ready(void)
{
bool ready;
while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) {
}
/*
* core 1 will set the ready flag once it is spinning in the
* above loop, waiting for a new IVT.
*/
ready = core1_info.ready;
SEMA_FreeSema(_CONTROL_SEMAPHORE);
return ready;
}
void core1_wait_ready(void)
{
/* Wait for the core to accept */
while (1) {
while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) {
}
/*
* core 1 will set the ready flag once it is spinning in the
* above loop, waiting for a new IVT.
*/
if (core1_info.ready) {
SEMA_FreeSema(_CONTROL_SEMAPHORE);
if (core1_is_ready()) {
break;
}
SEMA_FreeSema(_CONTROL_SEMAPHORE);
for (int i = 0; i < 10000; i++) {
}
}
......
......@@ -39,6 +39,9 @@ void core1_boot(void);
/* Reset core 1 into a state where it can accept a new payload */
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 */
void core1_wait_ready(void);
......
......@@ -119,8 +119,18 @@ static int do_load(struct load_info *info)
/*
* 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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment