1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <config.h> 8#include <mode/smp/ipi.h> 9#include <smp/lock.h> 10#include <util.h> 11 12#ifdef ENABLE_SMP_SUPPORT 13 14static IpiModeRemoteCall_t remoteCall; /* the remote call being requested */ 15 16static inline void init_ipi_args(IpiRemoteCall_t func, 17 word_t data1, word_t data2, word_t data3, 18 word_t mask) 19{ 20 remoteCall = (IpiModeRemoteCall_t)func; 21 ipi_args[0] = data1; 22 ipi_args[1] = data2; 23 ipi_args[2] = data3; 24 25 /* get number of cores involved in this IPI */ 26 totalCoreBarrier = popcountl(mask); 27} 28 29static void handleRemoteCall(IpiModeRemoteCall_t call, word_t arg0, 30 word_t arg1, word_t arg2, bool_t irqPath) 31{ 32 /* we gets spurious irq_remote_call_ipi calls, e.g. when handling IPI 33 * in lock while hardware IPI is pending. Guard against spurious IPIs! */ 34 if (clh_is_ipi_pending(getCurrentCPUIndex())) { 35 switch ((IpiRemoteCall_t)call) { 36 case IpiRemoteCall_Stall: 37 ipiStallCoreCallback(irqPath); 38 break; 39 40#ifdef CONFIG_HAVE_FPU 41 case IpiRemoteCall_switchFpuOwner: 42 switchLocalFpuOwner((user_fpu_state_t *)arg0); 43 break; 44#endif /* CONFIG_HAVE_FPU */ 45 46 case IpiRemoteCall_InvalidateTranslationSingle: 47 invalidateTranslationSingleLocal(arg0); 48 break; 49 50 case IpiRemoteCall_InvalidateTranslationASID: 51 invalidateTranslationASIDLocal(arg0); 52 break; 53 54 case IpiRemoteCall_InvalidateTranslationAll: 55 invalidateTranslationAllLocal(); 56 break; 57 58 case IpiRemoteCall_MaskPrivateInterrupt: 59 maskInterrupt(arg0, IDX_TO_IRQT(arg1)); 60 break; 61 62#if defined CONFIG_ARM_HYPERVISOR_SUPPORT && defined ENABLE_SMP_SUPPORT 63 case IpiRemoteCall_VCPUInjectInterrupt: { 64 virq_t virq; 65 virq.words[0] = arg2; 66 handleVCPUInjectInterruptIPI((vcpu_t *) arg0, arg1, virq); 67 break; 68 } 69#endif 70 71 default: 72 fail("Invalid remote call"); 73 break; 74 } 75 76 big_kernel_lock.node_owners[getCurrentCPUIndex()].ipi = 0; 77 ipi_wait(totalCoreBarrier); 78 } 79} 80 81void ipi_send_mask(irq_t ipi, word_t mask, bool_t isBlocking) 82{ 83 generic_ipi_send_mask(ipi, mask, isBlocking); 84} 85#endif /* ENABLE_SMP_SUPPORT */ 86