smp.h revision 196196
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 196196 2009-08-13 17:09:45Z attilio $ 27 */ 28 29#ifndef _MACHINE_SMP_H_ 30#define _MACHINE_SMP_H_ 31 32#ifdef SMP 33 34#define CPU_TICKSYNC 1 35#define CPU_STICKSYNC 2 36#define CPU_INIT 3 37#define CPU_BOOTSTRAP 4 38 39#ifndef LOCORE 40 41#include <machine/intr_machdep.h> 42#include <machine/pcb.h> 43#include <machine/tte.h> 44 45#define IDR_BUSY 0x0000000000000001ULL 46#define IDR_NACK 0x0000000000000002ULL 47#define IDR_CHEETAH_ALL_BUSY 0x5555555555555555ULL 48#define IDR_CHEETAH_ALL_NACK (~IDR_CHEETAH_ALL_BUSY) 49#define IDR_CHEETAH_MAX_BN_PAIRS 32 50#define IDR_JALAPENO_MAX_BN_PAIRS 4 51 52#define IDC_ITID_SHIFT 14 53#define IDC_BN_SHIFT 24 54 55#define IPI_AST PIL_AST 56#define IPI_RENDEZVOUS PIL_RENDEZVOUS 57#define IPI_PREEMPT PIL_PREEMPT 58#define IPI_STOP PIL_STOP 59#define IPI_STOP_HARD PIL_STOP 60 61#define IPI_RETRIES 5000 62 63struct cpu_start_args { 64 u_int csa_count; 65 u_int csa_mid; 66 u_int csa_state; 67 vm_offset_t csa_pcpu; 68 u_long csa_tick; 69 u_long csa_stick; 70 u_long csa_ver; 71 struct tte csa_ttes[PCPU_PAGES]; 72}; 73 74struct ipi_cache_args { 75 u_int ica_mask; 76 vm_paddr_t ica_pa; 77}; 78 79struct ipi_tlb_args { 80 u_int ita_mask; 81 struct pmap *ita_pmap; 82 u_long ita_start; 83 u_long ita_end; 84}; 85#define ita_va ita_start 86 87struct pcpu; 88 89extern struct pcb stoppcbs[]; 90 91void cpu_mp_bootstrap(struct pcpu *pc); 92void cpu_mp_shutdown(void); 93 94typedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long); 95extern cpu_ipi_selected_t *cpu_ipi_selected; 96 97void mp_init(void); 98 99extern struct mtx ipi_mtx; 100extern struct ipi_cache_args ipi_cache_args; 101extern struct ipi_tlb_args ipi_tlb_args; 102 103extern char *mp_tramp_code; 104extern u_long mp_tramp_code_len; 105extern u_long mp_tramp_tlb_slots; 106extern u_long mp_tramp_func; 107 108extern void mp_startup(void); 109 110extern char tl_ipi_cheetah_dcache_page_inval[]; 111extern char tl_ipi_spitfire_dcache_page_inval[]; 112extern char tl_ipi_spitfire_icache_page_inval[]; 113 114extern char tl_ipi_level[]; 115extern char tl_ipi_tlb_context_demap[]; 116extern char tl_ipi_tlb_page_demap[]; 117extern char tl_ipi_tlb_range_demap[]; 118 119static __inline void 120ipi_all_but_self(u_int ipi) 121{ 122 123 cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi); 124} 125 126static __inline void 127ipi_selected(u_int cpus, u_int ipi) 128{ 129 130 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); 131} 132 133#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 134 135static __inline void * 136ipi_dcache_page_inval(void *func, vm_paddr_t pa) 137{ 138 struct ipi_cache_args *ica; 139 140 if (smp_cpus == 1) 141 return (NULL); 142 ica = &ipi_cache_args; 143 mtx_lock_spin(&ipi_mtx); 144 ica->ica_mask = all_cpus; 145 ica->ica_pa = pa; 146 cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 147 return (&ica->ica_mask); 148} 149 150static __inline void * 151ipi_icache_page_inval(void *func, vm_paddr_t pa) 152{ 153 struct ipi_cache_args *ica; 154 155 if (smp_cpus == 1) 156 return (NULL); 157 ica = &ipi_cache_args; 158 mtx_lock_spin(&ipi_mtx); 159 ica->ica_mask = all_cpus; 160 ica->ica_pa = pa; 161 cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 162 return (&ica->ica_mask); 163} 164 165static __inline void * 166ipi_tlb_context_demap(struct pmap *pm) 167{ 168 struct ipi_tlb_args *ita; 169 u_int cpus; 170 171 if (smp_cpus == 1) 172 return (NULL); 173 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 174 return (NULL); 175 ita = &ipi_tlb_args; 176 mtx_lock_spin(&ipi_mtx); 177 ita->ita_mask = cpus | PCPU_GET(cpumask); 178 ita->ita_pmap = pm; 179 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 180 (u_long)ita); 181 return (&ita->ita_mask); 182} 183 184static __inline void * 185ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 186{ 187 struct ipi_tlb_args *ita; 188 u_int cpus; 189 190 if (smp_cpus == 1) 191 return (NULL); 192 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 193 return (NULL); 194 ita = &ipi_tlb_args; 195 mtx_lock_spin(&ipi_mtx); 196 ita->ita_mask = cpus | PCPU_GET(cpumask); 197 ita->ita_pmap = pm; 198 ita->ita_va = va; 199 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 200 return (&ita->ita_mask); 201} 202 203static __inline void * 204ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 205{ 206 struct ipi_tlb_args *ita; 207 u_int cpus; 208 209 if (smp_cpus == 1) 210 return (NULL); 211 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 212 return (NULL); 213 ita = &ipi_tlb_args; 214 mtx_lock_spin(&ipi_mtx); 215 ita->ita_mask = cpus | PCPU_GET(cpumask); 216 ita->ita_pmap = pm; 217 ita->ita_start = start; 218 ita->ita_end = end; 219 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 220 return (&ita->ita_mask); 221} 222 223static __inline void 224ipi_wait(void *cookie) 225{ 226 volatile u_int *mask; 227 228 if ((mask = cookie) != NULL) { 229 atomic_clear_int(mask, PCPU_GET(cpumask)); 230 while (*mask != 0) 231 ; 232 mtx_unlock_spin(&ipi_mtx); 233 } 234} 235 236#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 237 238#endif /* !LOCORE */ 239 240#else 241 242#ifndef LOCORE 243 244static __inline void * 245ipi_dcache_page_inval(void *func, vm_paddr_t pa) 246{ 247 248 return (NULL); 249} 250 251static __inline void * 252ipi_icache_page_inval(void *func, vm_paddr_t pa) 253{ 254 255 return (NULL); 256} 257 258static __inline void * 259ipi_tlb_context_demap(struct pmap *pm) 260{ 261 262 return (NULL); 263} 264 265static __inline void * 266ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 267{ 268 269 return (NULL); 270} 271 272static __inline void * 273ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 274{ 275 276 return (NULL); 277} 278 279static __inline void 280ipi_wait(void *cookie) 281{ 282 283} 284 285static __inline void 286tl_ipi_cheetah_dcache_page_inval(void) 287{ 288 289} 290 291static __inline void 292tl_ipi_spitfire_dcache_page_inval(void) 293{ 294 295} 296 297static __inline void 298tl_ipi_spitfire_icache_page_inval(void) 299{ 300 301} 302 303#endif /* !LOCORE */ 304 305#endif /* SMP */ 306 307#endif /* !_MACHINE_SMP_H_ */ 308