diff --git a/hypervisor/arch/riscv/Makefile b/hypervisor/arch/riscv/Makefile index 54f0c6517..d52cbec11 100644 --- a/hypervisor/arch/riscv/Makefile +++ b/hypervisor/arch/riscv/Makefile @@ -29,6 +29,7 @@ HOST_S_SRCS += arch/riscv/dummy_entry.S # HV host C sources HOST_C_SRCS += arch/riscv/dummy.c +HOST_C_SRCS += arch/riscv/sbi.c # Virtual platform assembly sources VP_S_SRCS += diff --git a/hypervisor/arch/riscv/sbi.c b/hypervisor/arch/riscv/sbi.c index 7834b8a77..73a43c7df 100644 --- a/hypervisor/arch/riscv/sbi.c +++ b/hypervisor/arch/riscv/sbi.c @@ -9,6 +9,7 @@ #include #include +#include /** * An ECALL is used as the control transfer instruction between the @@ -57,3 +58,47 @@ static sbiret sbi_ecall(uint64_t arg0, uint64_t arg1, uint64_t arg2, return ret; } + +/** + * Implemented IPI functionality using the SBI IPI Extension (EID #0x735049). + * Legacy SBI extensions are not supported in ACRN. + */ +static int64_t sbi_send_ipi(uint64_t mask, uint64_t mask_base) +{ + sbiret ret = sbi_ecall(mask, mask_base, 0UL, 0UL, 0UL, 0UL, SBI_IPI_FID_SEND_IPI, SBI_EID_IPI); + + if (ret.error != SBI_SUCCESS) { + pr_err("%s: Failed to send IPI by SBI, error code: %lx", __func__, ret.error); + } + + return ret.error; +} + +/** + * msg_type is currently unused. + * + * At present, only IPI_NOTIFY_CPU is supported, covering two use cases: + * - SMP call + * - Kick pCPU out of non-root mode + * + * Callers should invoke this function with: + * arch_send_single_ipi(pcpu_id, IPI_NOTIFY_CPU); + * + * msg_type is retained for future extensions and to stay aligned with + * the function prototype used on other architectures (e.g. x86). + */ +void arch_send_single_ipi(uint16_t pcpu_id, __unused uint32_t msg_type) +{ + sbi_send_ipi((1UL << pcpu_id), 0UL); +} + +/** + * Similar to arch_send_single_ipi() regards to msg_type. + * + * Callers should invoke this function with: + * arch_send_dest_ipi_mask(dest_mask, IPI_NOTIFY_CPU); + */ +void arch_send_dest_ipi_mask(uint64_t dest_mask, __unused uint32_t msg_type) +{ + sbi_send_ipi(dest_mask, 0UL); +} diff --git a/hypervisor/include/arch/riscv/asm/cpu.h b/hypervisor/include/arch/riscv/asm/cpu.h new file mode 100644 index 000000000..e69de29bb diff --git a/hypervisor/include/arch/riscv/asm/irq.h b/hypervisor/include/arch/riscv/asm/irq.h new file mode 100644 index 000000000..880db7d0d --- /dev/null +++ b/hypervisor/include/arch/riscv/asm/irq.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023-2025 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Authors: + * Haicheng Li + */ + +#ifndef RISCV_IRQ_H +#define RISCV_IRQ_H + +#define IPI_NOTIFY_CPU 0 + +#endif /* RISCV_IRQ_H */ diff --git a/hypervisor/include/arch/riscv/asm/sbi.h b/hypervisor/include/arch/riscv/asm/sbi.h index b97f49bc3..87c7acc92 100644 --- a/hypervisor/include/arch/riscv/asm/sbi.h +++ b/hypervisor/include/arch/riscv/asm/sbi.h @@ -97,4 +97,7 @@ typedef struct { }; } sbiret; +void arch_send_single_ipi(uint16_t pcpu_id, __unused uint32_t msg_type); +void arch_send_dest_ipi_mask(uint64_t dest_mask, __unused uint32_t msg_type); + #endif /* RISCV_SBI_H */