smp.h revision 135943
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 135943 2004-09-29 21:39:36Z kensmith $ 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 5000 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 vm_paddr_t 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 mtx ipi_mtx; 88extern struct ipi_cache_args ipi_cache_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_cheetah_dcache_page_inval[]; 100extern char tl_ipi_spitfire_dcache_page_inval[]; 101extern char tl_ipi_spitfire_icache_page_inval[]; 102 103extern char tl_ipi_level[]; 104extern char tl_ipi_tlb_context_demap[]; 105extern char tl_ipi_tlb_page_demap[]; 106extern char tl_ipi_tlb_range_demap[]; 107 108#ifdef SMP 109 110#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 111 112static __inline void * 113ipi_dcache_page_inval(void *func, vm_paddr_t pa) 114{ 115 struct ipi_cache_args *ica; 116 117 if (smp_cpus == 1) 118 return (NULL); 119 ica = &ipi_cache_args; 120 mtx_lock_spin(&ipi_mtx); 121 ica->ica_mask = all_cpus; 122 ica->ica_pa = pa; 123 cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 124 return (&ica->ica_mask); 125} 126 127static __inline void * 128ipi_icache_page_inval(void *func, vm_paddr_t pa) 129{ 130 struct ipi_cache_args *ica; 131 132 if (smp_cpus == 1) 133 return (NULL); 134 ica = &ipi_cache_args; 135 mtx_lock_spin(&ipi_mtx); 136 ica->ica_mask = all_cpus; 137 ica->ica_pa = pa; 138 cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 139 return (&ica->ica_mask); 140} 141 142static __inline void * 143ipi_tlb_context_demap(struct pmap *pm) 144{ 145 struct ipi_tlb_args *ita; 146 u_int cpus; 147 148 if (smp_cpus == 1) 149 return (NULL); 150 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 151 return (NULL); 152 ita = &ipi_tlb_args; 153 mtx_lock_spin(&ipi_mtx); 154 ita->ita_mask = cpus | PCPU_GET(cpumask); 155 ita->ita_pmap = pm; 156 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 157 (u_long)ita); 158 return (&ita->ita_mask); 159} 160 161static __inline void * 162ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 163{ 164 struct ipi_tlb_args *ita; 165 u_int cpus; 166 167 if (smp_cpus == 1) 168 return (NULL); 169 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 170 return (NULL); 171 ita = &ipi_tlb_args; 172 mtx_lock_spin(&ipi_mtx); 173 ita->ita_mask = cpus | PCPU_GET(cpumask); 174 ita->ita_pmap = pm; 175 ita->ita_va = va; 176 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 177 return (&ita->ita_mask); 178} 179 180static __inline void * 181ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 182{ 183 struct ipi_tlb_args *ita; 184 u_int cpus; 185 186 if (smp_cpus == 1) 187 return (NULL); 188 if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 189 return (NULL); 190 ita = &ipi_tlb_args; 191 mtx_lock_spin(&ipi_mtx); 192 ita->ita_mask = cpus | PCPU_GET(cpumask); 193 ita->ita_pmap = pm; 194 ita->ita_start = start; 195 ita->ita_end = end; 196 cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 197 return (&ita->ita_mask); 198} 199 200static __inline void 201ipi_wait(void *cookie) 202{ 203 u_int *volatile mask; 204 205 if ((mask = cookie) != NULL) { 206 atomic_clear_int(mask, PCPU_GET(cpumask)); 207 while (*mask != 0) 208 ; 209 mtx_unlock_spin(&ipi_mtx); 210 } 211} 212 213#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 214 215#else 216 217static __inline void * 218ipi_dcache_page_inval(void *func, vm_paddr_t pa) 219{ 220 return (NULL); 221} 222 223static __inline void * 224ipi_icache_page_inval(void *func, vm_paddr_t pa) 225{ 226 return (NULL); 227} 228 229static __inline void * 230ipi_tlb_context_demap(struct pmap *pm) 231{ 232 return (NULL); 233} 234 235static __inline void * 236ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 237{ 238 return (NULL); 239} 240 241static __inline void * 242ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 243{ 244 return (NULL); 245} 246 247static __inline void 248ipi_wait(void *cookie) 249{ 250} 251 252#endif /* SMP */ 253 254#endif /* !LOCORE */ 255 256#endif /* !_MACHINE_SMP_H_ */ 257