1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13#include <config.h> 14#include <mode/smp/ipi.h> 15#include <smp/lock.h> 16#include <util.h> 17 18#ifdef ENABLE_SMP_SUPPORT 19 20static IpiModeRemoteCall_t remoteCall; /* the remote call being requested */ 21 22static inline void init_ipi_args(IpiModeRemoteCall_t func, 23 word_t data1, word_t data2, word_t data3, 24 word_t mask) 25{ 26 remoteCall = func; 27 ipi_args[0] = data1; 28 ipi_args[1] = data2; 29 ipi_args[2] = data3; 30 31 /* get number of cores involved in this IPI */ 32 totalCoreBarrier = popcountl(mask); 33} 34 35static void handleRemoteCall(IpiModeRemoteCall_t call, word_t arg0, 36 word_t arg1, word_t arg2, bool_t irqPath) 37{ 38 /* we gets spurious irq_remote_call_ipi calls, e.g. when handling IPI 39 * in lock while hardware IPI is pending. Guard against spurious IPIs! */ 40 if (clh_is_ipi_pending(getCurrentCPUIndex())) { 41 switch ((IpiRemoteCall_t)call) { 42 case IpiRemoteCall_Stall: 43 ipiStallCoreCallback(irqPath); 44 break; 45 46#ifdef CONFIG_HAVE_FPU 47 case IpiRemoteCall_switchFpuOwner: 48 switchLocalFpuOwner((user_fpu_state_t *)arg0); 49 break; 50#endif /* CONFIG_HAVE_FPU */ 51 52 case IpiRemoteCall_InvalidateTranslationSingle: 53 invalidateTranslationSingleLocal(arg0); 54 break; 55 56 case IpiRemoteCall_InvalidateTranslationASID: 57 invalidateTranslationASIDLocal(arg0); 58 break; 59 60 case IpiRemoteCall_InvalidateTranslationAll: 61 invalidateTranslationAllLocal(); 62 break; 63 64 default: 65 fail("Invalid remote call"); 66 break; 67 } 68 69 big_kernel_lock.node_owners[getCurrentCPUIndex()].ipi = 0; 70 ipi_wait(totalCoreBarrier); 71 } 72} 73 74void ipi_send_mask(irq_t ipi, word_t mask, bool_t isBlocking) 75{ 76 generic_ipi_send_mask(ipi, mask, isBlocking); 77} 78#endif /* ENABLE_SMP_SUPPORT */ 79