17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5ae115bc7Smrj * Common Development and Distribution License (the "License"). 6ae115bc7Smrj * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21ae115bc7Smrj 227c478bd9Sstevel@tonic-gate /* 23f34a7178SJoe Bonasera * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24ae115bc7Smrj * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 287c478bd9Sstevel@tonic-gate #include <sys/param.h> 297c478bd9Sstevel@tonic-gate #include <sys/thread.h> 307c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h> 317c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 327c478bd9Sstevel@tonic-gate #include <sys/systm.h> 33ae115bc7Smrj #include <sys/promif.h> 34f34a7178SJoe Bonasera #include <sys/xc_levels.h> 35*b885580bSAlexander Kolbasov #include <sys/spl.h> 36*b885580bSAlexander Kolbasov #include <sys/bitmap.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 397c478bd9Sstevel@tonic-gate * Interrupt another CPU. 407c478bd9Sstevel@tonic-gate * This is useful to make the other CPU go through a trap so that 417c478bd9Sstevel@tonic-gate * it recognizes an address space trap (AST) for preempting a thread. 427c478bd9Sstevel@tonic-gate * 437c478bd9Sstevel@tonic-gate * It is possible to be preempted here and be resumed on the CPU 447c478bd9Sstevel@tonic-gate * being poked, so it isn't an error to poke the current CPU. 457c478bd9Sstevel@tonic-gate * We could check this and still get preempted after the check, so 467c478bd9Sstevel@tonic-gate * we don't bother. 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate void 497c478bd9Sstevel@tonic-gate poke_cpu(int cpun) 507c478bd9Sstevel@tonic-gate { 51ae115bc7Smrj if (panicstr) 52ae115bc7Smrj return; 537c478bd9Sstevel@tonic-gate /* 547c478bd9Sstevel@tonic-gate * We don't need to receive an ACK from the CPU being poked, 557c478bd9Sstevel@tonic-gate * so just send out a directed interrupt. 567c478bd9Sstevel@tonic-gate */ 577c478bd9Sstevel@tonic-gate send_dirint(cpun, XC_CPUPOKE_PIL); 587c478bd9Sstevel@tonic-gate } 59*b885580bSAlexander Kolbasov 60*b885580bSAlexander Kolbasov /* 61*b885580bSAlexander Kolbasov * Call a function on a target CPU 62*b885580bSAlexander Kolbasov */ 63*b885580bSAlexander Kolbasov void 64*b885580bSAlexander Kolbasov cpu_call(cpu_t *cp, cpu_call_func_t func, uintptr_t arg1, uintptr_t arg2) 65*b885580bSAlexander Kolbasov { 66*b885580bSAlexander Kolbasov cpuset_t set; 67*b885580bSAlexander Kolbasov 68*b885580bSAlexander Kolbasov if (panicstr) 69*b885580bSAlexander Kolbasov return; 70*b885580bSAlexander Kolbasov 71*b885580bSAlexander Kolbasov /* 72*b885580bSAlexander Kolbasov * Prevent CPU from going off-line 73*b885580bSAlexander Kolbasov */ 74*b885580bSAlexander Kolbasov kpreempt_disable(); 75*b885580bSAlexander Kolbasov 76*b885580bSAlexander Kolbasov /* 77*b885580bSAlexander Kolbasov * If we are on the target CPU, call the function directly, but raise 78*b885580bSAlexander Kolbasov * the PIL to XC_PIL. 79*b885580bSAlexander Kolbasov * This guarantees that functions called via cpu_call() can not ever 80*b885580bSAlexander Kolbasov * interrupt each other. 81*b885580bSAlexander Kolbasov */ 82*b885580bSAlexander Kolbasov if (CPU == cp) { 83*b885580bSAlexander Kolbasov int save_spl = splr(ipltospl(XC_HI_PIL)); 84*b885580bSAlexander Kolbasov 85*b885580bSAlexander Kolbasov (*func)(arg1, arg2); 86*b885580bSAlexander Kolbasov splx(save_spl); 87*b885580bSAlexander Kolbasov } else { 88*b885580bSAlexander Kolbasov CPUSET_ONLY(set, cp->cpu_id); 89*b885580bSAlexander Kolbasov xc_call((xc_arg_t)arg1, (xc_arg_t)arg2, 0, CPUSET2BV(set), 90*b885580bSAlexander Kolbasov (xc_func_t)func); 91*b885580bSAlexander Kolbasov } 92*b885580bSAlexander Kolbasov kpreempt_enable(); 93*b885580bSAlexander Kolbasov } 94