source: mainline/kernel/arch/sparc64/src/smp/sun4u/ipi.c

Last change on this file was d19b3fc, checked in by Jakub Jermar <jakub@…>, 7 years ago

Remove smp_call

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[a9ac978]1/*
[df4ed85]2 * Copyright (c) 2006 Jakub Jermar
[a9ac978]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[c5429fe]29/** @addtogroup kernel_sparc64
[a9ac978]30 * @{
31 */
32/** @file
33 */
34
35#include <smp/ipi.h>
[7328ff4]36#include <arch/barrier.h>
[63e27ef]37#include <assert.h>
[00b38a3]38#include <cpu.h>
[b3f8fb7]39#include <arch.h>
[00b38a3]40#include <arch/cpu.h>
41#include <arch/asm.h>
42#include <config.h>
43#include <mm/tlb.h>
44#include <arch/interrupt.h>
45#include <arch/trap/interrupt.h>
[05882233]46#include <barrier.h>
[00b38a3]47#include <preemption.h>
48#include <time/delay.h>
49#include <panic.h>
[a9ac978]50
[965dc18]51/** Set the contents of the outgoing interrupt vector data.
52 *
53 * The first data item (data 0) will be set to the value of func, the
54 * rest of the vector will contain zeros.
55 *
56 * This is a helper function used from within the cross_call function.
57 *
58 * @param func value the first data item of the vector will be set to
59 */
[1433ecda]60static inline void set_intr_w_data(void (*func)(void))
[965dc18]61{
62#if defined (US)
63 asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func);
64 asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
65 asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
66#elif defined (US3)
67 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func);
68 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0);
69 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0);
70 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0);
71 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0);
72 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0);
73 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0);
74 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0);
75#endif
76}
77
[00b38a3]78/** Invoke function on another processor.
79 *
80 * Currently, only functions without arguments are supported.
81 * Supporting more arguments in the future should be no big deal.
82 *
83 * Interrupts must be disabled prior to this call.
84 *
85 * @param mid MID of the target processor.
86 * @param func Function to be invoked.
87 */
[1433ecda]88static void cross_call(int mid, void (*func)(void))
[00b38a3]89{
90 uint64_t status;
91 bool done;
92
93 /*
[771cd22]94 * This function might enable interrupts for a while.
[00b38a3]95 * In order to prevent migration to another processor,
96 * we explicitly disable preemption.
97 */
[a35b458]98
[00b38a3]99 preemption_disable();
[a35b458]100
[00b38a3]101 status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
102 if (status & INTR_DISPATCH_STATUS_BUSY)
[95c4776]103 panic("Interrupt Dispatch Status busy bit set\n");
[a35b458]104
[63e27ef]105 assert(!(pstate_read() & PSTATE_IE_BIT));
[a35b458]106
[00b38a3]107 do {
[965dc18]108 set_intr_w_data(func);
109 asi_u64_write(ASI_INTR_W,
[454f1da]110 (mid << INTR_VEC_DISPATCH_MID_SHIFT) |
[965dc18]111 VA_INTR_W_DISPATCH, 0);
[a35b458]112
[00b38a3]113 membar();
[a35b458]114
[00b38a3]115 do {
116 status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
117 } while (status & INTR_DISPATCH_STATUS_BUSY);
[a35b458]118
[00b38a3]119 done = !(status & INTR_DISPATCH_STATUS_NACK);
120 if (!done) {
121 /*
122 * Prevent deadlock.
[1b20da0]123 */
[00b38a3]124 (void) interrupts_enable();
125 delay(20 + (tick_read() & 0xff));
126 (void) interrupts_disable();
127 }
[bb4c9fca]128 } while (!done);
[a35b458]129
[00b38a3]130 preemption_enable();
131}
132
133/*
134 * Deliver IPI to all processors except the current one.
135 *
136 * The sparc64 architecture does not support any group addressing
137 * which is found, for instance, on ia32 and amd64. Therefore we
138 * need to simulate the broadcast by sending the message to
139 * all target processors step by step.
140 *
141 * We assume that interrupts are disabled.
142 *
143 * @param ipi IPI number.
144 */
[a9ac978]145void ipi_broadcast_arch(int ipi)
146{
[6c441cf8]147 unsigned int i;
[a35b458]148
[1433ecda]149 void (*func)(void);
[a35b458]150
[00b38a3]151 switch (ipi) {
152 case IPI_TLB_SHOOTDOWN:
153 func = tlb_shootdown_ipi_recv;
154 break;
155 default:
[95c4776]156 panic("Unknown IPI (%d).\n", ipi);
[00b38a3]157 break;
158 }
[a35b458]159
[00b38a3]160 /*
161 * As long as we don't support hot-plugging
162 * or hot-unplugging of CPUs, we can walk
163 * the cpus array and read processor's MID
164 * without locking.
165 */
[a35b458]166
[00b38a3]167 for (i = 0; i < config.cpu_active; i++) {
168 if (&cpus[i] == CPU)
169 continue; /* skip the current CPU */
170
171 cross_call(cpus[i].arch.mid, func);
172 }
[a9ac978]173}
174
175/** @}
176 */
Note: See TracBrowser for help on using the repository browser.