smp.h revision 100718
1/*- 2 * Copyright (c) 2001 Jake Burkholder. 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 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/sparc64/include/smp.h 100718 2002-07-26 15:54:04Z jake $ 27 */ 28 29#ifndef _MACHINE_SMP_H_ 30#define _MACHINE_SMP_H_ 31 32#define CPU_CLKSYNC 1 33#define CPU_INIT 2 34#define CPU_BOOTSTRAP 3 35 36#ifndef LOCORE 37 38#include <machine/intr_machdep.h> 39#include <machine/tte.h> 40 41#define IDR_BUSY (1<<0) 42#define IDR_NACK (1<<1) 43 44#define IPI_AST PIL_AST 45#define IPI_RENDEZVOUS PIL_RENDEZVOUS 46#define IPI_STOP PIL_STOP 47 48#define IPI_RETRIES 100 49 50struct cpu_start_args { 51 u_int csa_count; 52 u_int csa_mid; 53 u_int csa_state; 54 vm_offset_t csa_pcpu; 55 u_long csa_tick; 56 u_long csa_ver; 57 struct tte csa_ttes[PCPU_PAGES]; 58}; 59 60struct ipi_cache_args { 61 u_int ica_mask; 62 u_long ica_pa; 63}; 64 65struct ipi_tlb_args { 66 u_int ita_mask; 67 struct pmap *ita_pmap; 68 u_long ita_start; 69 u_long ita_end; 70}; 71#define ita_va ita_start 72 73struct pcpu; 74 75void cpu_mp_bootstrap(struct pcpu *pc); 76void cpu_mp_shutdown(void); 77 78void cpu_ipi_selected(u_int cpus, u_long d0, u_long d1, u_long d2); 79void cpu_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2); 80 81void ipi_selected(u_int cpus, u_int ipi); 82void ipi_all(u_int ipi); 83void ipi_all_but_self(u_int ipi); 84 85vm_offset_t mp_tramp_alloc(void); 86 87extern struct ipi_cache_args ipi_cache_args; 88extern struct ipi_level_args ipi_level_args; 89extern struct ipi_tlb_args ipi_tlb_args; 90 91extern vm_offset_t mp_tramp; 92extern char *mp_tramp_code; 93extern u_long mp_tramp_code_len; 94extern u_long mp_tramp_tlb_slots; 95extern u_long mp_tramp_func; 96 97extern void mp_startup(void); 98 99extern char tl_ipi_dcache_page_inval[]; 100extern char tl_ipi_icache_page_inval[]; 101extern char tl_ipi_level[]; 102extern char tl_ipi_tlb_context_demap[]; 103extern char tl_ipi_tlb_page_demap[]; 104extern char tl_ipi_tlb_range_demap[]; 105 106#ifdef SMP 107 108static __inline void * 109ipi_dcache_page_inval(vm_offset_t pa) 110{ 111 struct ipi_cache_args *ica; 112 113 if (smp_cpus == 1) 114 return (NULL); 115 ica = &ipi_cache_args; 116 ica->ica_mask = all_cpus; 117 ica->ica_pa = pa; 118 cpu_ipi_selected(PCPU_GET(other_cpus), 0, 119 (u_long)tl_ipi_dcache_page_inval, (u_long)ica); 120 return (&ica->ica_mask); 121} 122 123static __inline void * 124ipi_icache_page_inval(vm_offset_t pa) 125{ 126 struct ipi_cache_args *ica; 127 128 if (smp_cpus == 1) 129 return (NULL); 130 ica = &ipi_cache_args; 131 ica->ica_mask = all_cpus; 132 ica->ica_pa = pa; 133 cpu_ipi_selected(PCPU_GET(other_cpus), 0, 134 (u_long)tl_ipi_icache_page_inval, (u_long)ica); 135 return (&ica->ica_mask); 136} 137 138#ifdef _MACHINE_PMAP_H_ 139 140static __inline void * 141ipi_tlb_context_demap(struct pmap *pm) 142{ 143 struct ipi_tlb_args *ita; 144 u_int cpus; 145 146 if (smp_cpus == 1) 147 return (NULL); 148 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 149 return (NULL); 150 ita = &ipi_tlb_args; 151 ita->ita_mask = cpus | PCPU_GET(cpumask); 152 ita->ita_pmap = pm; 153 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 154 (u_long)ita); 155 return (&ita->ita_mask); 156} 157 158static __inline void * 159ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 160{ 161 struct ipi_tlb_args *ita; 162 u_int cpus; 163 164 if (smp_cpus == 1) 165 return (NULL); 166 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 167 return (NULL); 168 ita = &ipi_tlb_args; 169 ita->ita_mask = cpus | PCPU_GET(cpumask); 170 ita->ita_pmap = pm; 171 ita->ita_va = va; 172 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 173 return (&ita->ita_mask); 174} 175 176static __inline void * 177ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 178{ 179 struct ipi_tlb_args *ita; 180 u_int cpus; 181 182 if (smp_cpus == 1) 183 return (NULL); 184 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 185 return (NULL); 186 ita = &ipi_tlb_args; 187 ita->ita_mask = cpus | PCPU_GET(cpumask); 188 ita->ita_pmap = pm; 189 ita->ita_start = start; 190 ita->ita_end = end; 191 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 192 return (&ita->ita_mask); 193} 194 195static __inline void 196ipi_wait(void *cookie) 197{ 198 u_int *volatile mask; 199 200 if ((mask = cookie) != NULL) { 201 atomic_clear_int(mask, PCPU_GET(cpumask)); 202 while (*mask != 0) 203 ; 204 } 205} 206 207#endif 208 209#else 210 211static __inline void * 212ipi_dcache_page_inval(vm_offset_t pa) 213{ 214 return (NULL); 215} 216 217static __inline void * 218ipi_icache_page_inval(vm_offset_t pa) 219{ 220 return (NULL); 221} 222 223static __inline void * 224ipi_tlb_context_demap(struct pmap *pm) 225{ 226 return (NULL); 227} 228 229static __inline void * 230ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 231{ 232 return (NULL); 233} 234 235static __inline void * 236ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 237{ 238 return (NULL); 239} 240 241static __inline void 242ipi_wait(void *cookie) 243{ 244} 245 246#endif /* SMP */ 247 248#endif /* !LOCORE */ 249 250#endif /* !_MACHINE_SMP_H_ */ 251