summaryrefslogtreecommitdiff
path: root/lib/sbi/sbi_ipi.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sbi/sbi_ipi.c')
-rw-r--r--lib/sbi/sbi_ipi.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c
index b9f6205..49a3ae5 100644
--- a/lib/sbi/sbi_ipi.c
+++ b/lib/sbi/sbi_ipi.c
@@ -11,6 +11,7 @@
#include <sbi/riscv_asm.h>
#include <sbi/riscv_atomic.h>
#include <sbi/riscv_barrier.h>
+#include <sbi/sbi_console.h>
#include <sbi/sbi_bitops.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
@@ -150,7 +151,7 @@ static struct sbi_ipi_event_ops ipi_smode_ops = {
};
static u32 ipi_smode_event = SBI_IPI_EVENT_MAX;
-
+static unsigned long* amp_data_addr;
int sbi_ipi_send_smode(ulong hmask, ulong hbase)
{
return sbi_ipi_send_many(hmask, hbase, ipi_smode_event, NULL);
@@ -161,6 +162,34 @@ void sbi_ipi_clear_smode(void)
csr_clear(CSR_MIP, MIP_SSIP);
}
+int sbi_ipi_send_ext(u32 type, u32 hartid, u32 msg_bits)
+{
+ if (!amp_data_addr)
+ return SBI_EINVAL;
+
+ atomic_raw_set_bit(msg_bits, (void *)(amp_data_addr + hartid));
+
+ return sbi_ipi_send(sbi_scratch_thishart_ptr(), hartid, ipi_smode_event, NULL);
+}
+
+void sbi_ipi_set_amp_data_addr(unsigned long addr)
+{
+ amp_data_addr = (void *)addr;
+}
+
+void sbi_ipi_clear_ext_ipi(unsigned long addr)
+{
+ unsigned long msg_type;
+
+ if (!amp_data_addr)
+ return;
+
+ msg_type = atomic_raw_xchg_ulong(amp_data_addr + current_hartid(), 0);
+ *(unsigned long *)addr = msg_type;
+
+ sbi_ipi_clear_smode();
+}
+
static void sbi_ipi_process_halt(struct sbi_scratch *scratch)
{
sbi_hsm_hart_stop(scratch, true);