Mechanism to foward interupts between cores

This commit is contained in:
Justin Hammond 2023-01-11 11:25:47 +08:00
parent 27de351177
commit 0289bd83c5
3 changed files with 116 additions and 29 deletions

View file

@ -17,6 +17,10 @@ typedef enum {
IPC_MSG_RPMSG1 = IPC_IRQ_INT_SRC_BIT3, IPC_MSG_RPMSG1 = IPC_IRQ_INT_SRC_BIT3,
IPC_MSG_RPMSG2 = IPC_IRQ_INT_SRC_BIT4, IPC_MSG_RPMSG2 = IPC_IRQ_INT_SRC_BIT4,
IPC_MSG_RPMSG3 = IPC_IRQ_INT_SRC_BIT5, IPC_MSG_RPMSG3 = IPC_IRQ_INT_SRC_BIT5,
IPC_MSG_IRQFWD1 = IPC_IRQ_INT_SRC_BIT6,
IPC_MSG_IRQFWD2 = IPC_IRQ_INT_SRC_BIT7,
IPC_MSG_IRQFWD3 = IPC_IRQ_INT_SRC_BIT8,
IPC_MSG_IRQFWD4 = IPC_IRQ_INT_SRC_BIT9,
} IPC_MSG_Type; } IPC_MSG_Type;
#define IPC_MSG_MASK_ALL() ( IPC_MSG_PING || \ #define IPC_MSG_MASK_ALL() ( IPC_MSG_PING || \
@ -59,14 +63,16 @@ typedef enum {
void rpmsg_task(void *unused); void rpmsg_task(void *unused);
int ipc_mask_msg(IPC_MSG_Type msg); BL_Err_Type ipc_init();
int ipc_unmask_msg(IPC_MSG_Type msg);
int ipc_send_ping(GLB_CORE_ID_Type cpu);
int ipc_send_pong(GLB_CORE_ID_Type cpu);
int ipc_send_rpmsg(GLB_CORE_ID_Type cpu, uint32_t vector);
int ipc_mask_rpmsg(uint32_t vector);
int ipc_unmask_rpmsg(uint32_t vector);
BL_Err_Type ipc_mask_msg(IPC_MSG_Type msg);
BL_Err_Type ipc_unmask_msg(IPC_MSG_Type msg);
BL_Err_Type ipc_send_ping(GLB_CORE_ID_Type cpu);
BL_Err_Type ipc_send_pong(GLB_CORE_ID_Type cpu);
BL_Err_Type ipc_send_rpmsg(GLB_CORE_ID_Type cpu, uint32_t vector);
BL_Err_Type ipc_mask_rpmsg(uint32_t vector);
BL_Err_Type ipc_unmask_rpmsg(uint32_t vector);
BL_Err_Type ipc_forward_interupt(int irq, GLB_CORE_ID_Type targetcpu, IPC_MSG_Type msg);
bool ipc_is_core_alive(GLB_CORE_ID_Type cpu); bool ipc_is_core_alive(GLB_CORE_ID_Type cpu);

View file

@ -14,16 +14,36 @@ typedef struct
uint64_t m0ping; uint64_t m0ping;
uint64_t d0ping; uint64_t d0ping;
uint64_t lpping; uint64_t lpping;
struct irq_fwd {
GLB_CORE_ID_Type targetcpu;
irq_callback irq_handler;
} irq_fwd[4];
} ipc_status_t; } ipc_status_t;
ipc_status_t ipc_status; void ipc_isr_forward_default(int irq, void *param);
ipc_status_t ipc_status = {
.m0ping = 0,
.d0ping = 0,
.lpping = 0,
.irq_fwd = {
{ .targetcpu = GLB_CORE_ID_INVALID,
.irq_handler = ipc_isr_forward_default },
{ .targetcpu = GLB_CORE_ID_INVALID,
.irq_handler = ipc_isr_forward_default },
{ .targetcpu = GLB_CORE_ID_INVALID,
.irq_handler = ipc_isr_forward_default },
{ .targetcpu = GLB_CORE_ID_INVALID,
.irq_handler = ipc_isr_forward_default },
}
};
struct rpmsg_lite_instance *ipc_rpmsg; struct rpmsg_lite_instance *ipc_rpmsg;
struct rpmsg_lite_endpoint *ipc_rpmsg_default_endpoint; struct rpmsg_lite_endpoint *ipc_rpmsg_default_endpoint;
rpmsg_ns_handle ipc_rpmsg_ns; rpmsg_ns_handle ipc_rpmsg_ns;
rpmsg_queue_handle ipc_rpmsg_queue; rpmsg_queue_handle ipc_rpmsg_queue;
static int ipc_send_cmd(GLB_CORE_ID_Type targetcpu, uint32_t cmd); static BL_Err_Type ipc_send_cmd(GLB_CORE_ID_Type targetcpu, uint32_t cmd);
void ipc_m0_callback(uint32_t src) void ipc_m0_callback(uint32_t src)
{ {
@ -45,6 +65,13 @@ void ipc_m0_callback(uint32_t src)
LOG_D("IPC: Got Notify for Vector %d\r\n", ffs(src) - IPC_MSG_RPMSG0 - 1); LOG_D("IPC: Got Notify for Vector %d\r\n", ffs(src) - IPC_MSG_RPMSG0 - 1);
env_isr(ffs(src) - IPC_MSG_RPMSG0 - 1); env_isr(ffs(src) - IPC_MSG_RPMSG0 - 1);
break; break;
case IPC_MSG_IRQFWD1:
case IPC_MSG_IRQFWD2:
case IPC_MSG_IRQFWD3:
case IPC_MSG_IRQFWD4:
LOG_D("IPCIRQForward: Got Notify for Vector %d\r\n", src);
ipc_status.irq_fwd[ffs(src) - IPC_MSG_IRQFWD1 -1].irq_handler(ffs(src) - IPC_MSG_IRQFWD1 -1, (void *)src);
break;
} }
} }
@ -68,6 +95,13 @@ void ipc_d0_callback(uint32_t src)
LOG_D("IPC: Got Notify for Vector %d\r\n", ffs(src) - IPC_MSG_RPMSG0 - 1); LOG_D("IPC: Got Notify for Vector %d\r\n", ffs(src) - IPC_MSG_RPMSG0 - 1);
env_isr(ffs(src) - IPC_MSG_RPMSG0 - 1); env_isr(ffs(src) - IPC_MSG_RPMSG0 - 1);
break; break;
case IPC_MSG_IRQFWD1:
case IPC_MSG_IRQFWD2:
case IPC_MSG_IRQFWD3:
case IPC_MSG_IRQFWD4:
LOG_D("IPCIRQForward: Got Notify for Vector %d\r\n", src);
ipc_status.irq_fwd[ffs(src) - IPC_MSG_IRQFWD1 -1].irq_handler(ffs(src) - IPC_MSG_IRQFWD1 -1, (void *)src);
break;
} }
} }
@ -89,9 +123,27 @@ void ipc_lp_callback(uint32_t src)
case IPC_MSG_RPMSG3: case IPC_MSG_RPMSG3:
env_isr(ffs(src) - IPC_MSG_RPMSG0 - 1); env_isr(ffs(src) - IPC_MSG_RPMSG0 - 1);
break; break;
case IPC_MSG_IRQFWD1:
case IPC_MSG_IRQFWD2:
case IPC_MSG_IRQFWD3:
case IPC_MSG_IRQFWD4:
LOG_D("IPCIRQForward: Got Notify for Vector %d\r\n", src);
ipc_status.irq_fwd[ffs(src) - IPC_MSG_IRQFWD1 -1].irq_handler(ffs(src) - IPC_MSG_IRQFWD1 -1, (void *)src);
break;
} }
} }
void ipc_isr_forward(int irq, void *param)
{
IPC_MSG_Type msg = (IPC_MSG_Type)param;
LOG_D("IPC: Forwarding IRQ %d as IPC Interupt Command %d\r\n", irq, msg);
ipc_send_cmd(GLB_CORE_ID_D0, msg);
}
void ipc_isr_forward_default(int irq, void *param) {
LOG_D("Got Unhandled IPC IRQ Forward %d\r\n", irq);
}
void ipc_rpmsg_ns_callback(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data) void ipc_rpmsg_ns_callback(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data)
{ {
LOG_W("RPMSG TODO NS Callback Ran!\r\n"); LOG_W("RPMSG TODO NS Callback Ran!\r\n");
@ -201,14 +253,14 @@ void rpmsg_task(void *unused)
return; return;
} }
static int ipc_send_cmd(GLB_CORE_ID_Type targetcpu, uint32_t cmd) static BL_Err_Type ipc_send_cmd(GLB_CORE_ID_Type targetcpu, uint32_t cmd)
{ {
CHECK_PARAM(IS_GLB_CORE_ID_TYPE(targetcpu)); CHECK_PARAM(IS_GLB_CORE_ID_TYPE(targetcpu));
GLB_CORE_ID_Type mycpu = GLB_Get_Core_Type(); GLB_CORE_ID_Type mycpu = GLB_Get_Core_Type();
if (mycpu == targetcpu) if (mycpu == targetcpu)
{ {
LOG_W("IPC: Cannot send message %d to self\r\n", cmd); LOG_W("IPC: Cannot send message %d to self\r\n", cmd);
return 0; return INVALID;
} }
/* rpmsg needs to process each command before we send another, /* rpmsg needs to process each command before we send another,
so we will busy spin on the IPC interupt for the core to see when its cleared so we will busy spin on the IPC interupt for the core to see when its cleared
@ -218,30 +270,30 @@ static int ipc_send_cmd(GLB_CORE_ID_Type targetcpu, uint32_t cmd)
case GLB_CORE_ID_M0: case GLB_CORE_ID_M0:
if (IPC_IRQ_M0_Trigger_CPUx(targetcpu, cmd, IPC_TIMEOUT) != SUCCESS) if (IPC_IRQ_M0_Trigger_CPUx(targetcpu, cmd, IPC_TIMEOUT) != SUCCESS)
{ {
LOG_W("IPC: Failed to send message %d to %d\r\n", cmd, targetcpu); LOG_W("IPC: Failed to send IPC %d to %d\r\n", cmd, targetcpu);
return 0; return TIMEOUT;
} }
break; break;
case GLB_CORE_ID_D0: case GLB_CORE_ID_D0:
if (IPC_IRQ_D0_Trigger_CPUx(targetcpu, cmd, IPC_TIMEOUT) != SUCCESS) if (IPC_IRQ_D0_Trigger_CPUx(targetcpu, cmd, IPC_TIMEOUT) != SUCCESS)
{ {
LOG_W("IPC: Failed to send message %d to %d\r\n", cmd, targetcpu); LOG_W("IPC: Failed to send IPC %d to %d\r\n", cmd, targetcpu);
return 0; return TIMEOUT;
} }
break; break;
case GLB_CORE_ID_LP: case GLB_CORE_ID_LP:
if (IPC_IRQ_LP_Trigger_CPUx(targetcpu, cmd, IPC_TIMEOUT) != SUCCESS) if (IPC_IRQ_LP_Trigger_CPUx(targetcpu, cmd, IPC_TIMEOUT) != SUCCESS)
{ {
LOG_W("IPC: Failed to send message %d to %d\r\n", cmd, targetcpu); LOG_W("IPC: Failed to send IPC %d to %d\r\n", cmd, targetcpu);
return 0; return TIMEOUT;
} }
break; break;
case GLB_CORE_ID_MAX: case GLB_CORE_ID_MAX:
case GLB_CORE_ID_INVALID: case GLB_CORE_ID_INVALID:
LOG_W("Unknown CPU\r\n"); LOG_W("Unknown CPU\r\n");
return 0; return INVALID;
} }
return 1; return SUCCESS;
} }
bool ipc_is_core_alive(GLB_CORE_ID_Type cpu) bool ipc_is_core_alive(GLB_CORE_ID_Type cpu)
@ -258,44 +310,59 @@ bool ipc_is_core_alive(GLB_CORE_ID_Type cpu)
case GLB_CORE_ID_MAX: case GLB_CORE_ID_MAX:
case GLB_CORE_ID_INVALID: case GLB_CORE_ID_INVALID:
LOG_W("Unknown CPU\r\n"); LOG_W("Unknown CPU\r\n");
return 0; return false;
} }
return 0; return false;
} }
int ipc_send_ping(GLB_CORE_ID_Type cpu) BL_Err_Type ipc_send_ping(GLB_CORE_ID_Type cpu)
{ {
return ipc_send_cmd(cpu, IPC_MSG_PING); return ipc_send_cmd(cpu, IPC_MSG_PING);
} }
int ipc_send_pong(GLB_CORE_ID_Type cpu) BL_Err_Type ipc_send_pong(GLB_CORE_ID_Type cpu)
{ {
return ipc_send_cmd(cpu, IPC_MSG_PONG); return ipc_send_cmd(cpu, IPC_MSG_PONG);
} }
int ipc_send_rpmsg(GLB_CORE_ID_Type cpu, uint32_t cmd) BL_Err_Type ipc_send_rpmsg(GLB_CORE_ID_Type cpu, uint32_t cmd)
{ {
return ipc_send_cmd(cpu, (IPC_MSG_RPMSG0 + cmd)); return ipc_send_cmd(cpu, (IPC_MSG_RPMSG0 + cmd));
} }
int ipc_mask_msg(IPC_MSG_Type msg) BL_Err_Type ipc_mask_msg(IPC_MSG_Type msg)
{ {
/* XXX TODO - we need a Unmask Function in the SDK to go with this */ /* XXX TODO - we need a Unmask Function in the SDK to go with this */
return 1; return 1;
} }
int ipc_unmask_msg(IPC_MSG_Type msg) BL_Err_Type ipc_unmask_msg(IPC_MSG_Type msg)
{ {
/* XXX TODO - Need to write our own Unmask Function */ /* XXX TODO - Need to write our own Unmask Function */
return 1; return 1;
} }
int ipc_mask_rpmsg(uint32_t vector) BL_Err_Type ipc_mask_rpmsg(uint32_t vector)
{ {
return ipc_mask_msg(IPC_MSG_RPMSG0 + vector); return ipc_mask_msg(IPC_MSG_RPMSG0 + vector);
} }
int ipc_unmask_rpmsg(uint32_t vector) BL_Err_Type ipc_unmask_rpmsg(uint32_t vector)
{ {
return ipc_unmask_msg(IPC_MSG_RPMSG0 + vector); return ipc_unmask_msg(IPC_MSG_RPMSG0 + vector);
}
BL_Err_Type ipc_forward_interupt(int irq, GLB_CORE_ID_Type targetcpu, IPC_MSG_Type msg)
{
if (bflb_irq_attach(irq, ipc_isr_forward, (void *)msg) != 0) {
LOG_W("IPCFWD: Failed to attach IRQ %d\r\n", irq);
}
ipc_status.irq_fwd[(msg - IPC_MSG_IRQFWD1)].targetcpu = targetcpu;
bflb_irq_enable(irq);
LOG_I("IPCFWD: Forwarding IRQ %d to %d as message %d in slot %d\r\n", irq, targetcpu, msg, (msg - IPC_MSG_IRQFWD1));
return SUCCESS;
}
BL_Err_Type ipc_init() {
return SUCCESS;
} }

View file

@ -53,14 +53,28 @@ int main(void)
LOG_I("Console Started\r\n"); LOG_I("Console Started\r\n");
//pt_table_set_flash_operation(bflb_flash_erase, bflb_flash_write, bflb_flash_read); //pt_table_set_flash_operation(bflb_flash_erase, bflb_flash_write, bflb_flash_read);
//pt_table_dump(); //pt_table_dump();
LOG_I("Init IPC\r\n");
if (ipc_init() != SUCCESS) {
LOG_W("Failed to Initialize IPC\r\n");
}
LOG_I("About to Start RPMSG Task\r\n"); LOG_I("About to Start RPMSG Task\r\n");
if (xTaskCreate(rpmsg_task, "RPMSG_TASK", 2048, NULL, tskIDLE_PRIORITY + 1U, &rpmsg_task_handle) != pdPASS) if (xTaskCreate(rpmsg_task, "RPMSG_TASK", 2048, NULL, tskIDLE_PRIORITY + 1U, &rpmsg_task_handle) != pdPASS)
{ {
printf("\r\nFailed to create rpmsg task\r\n"); printf("\r\nFailed to create rpmsg task\r\n");
return -1; return -1;
} }
LOG_I("Forward SDH Interupt to D0\r\n");
if (ipc_forward_interupt(SDH_IRQn, GLB_CORE_ID_D0, IPC_MSG_IRQFWD1) != SUCCESS) {
LOG_W("Failed to Forward SDH Interupt\r\n");
}
#ifdef Zagitta_test
bflb_irq_set_pending(SDH_IRQn);
ipc_isr_forward(SDH_IRQn, IPC_MSG_IRQFWD1);
#endif
LOG_I("Starting Scheduler\r\n"); LOG_I("Starting Scheduler\r\n");
printf("main: mcause %x " PRINTF_BINARY_PATTERN_INT32 " \r\n", __get_MCAUSE(), PRINTF_BYTE_TO_BINARY_INT32(__get_MCAUSE()));
vTaskStartScheduler(); vTaskStartScheduler();
/* we should never get here */ /* we should never get here */