smp.h revision 169730
180708Sjake/*- 280708Sjake * Copyright (c) 2001 Jake Burkholder. 380708Sjake * All rights reserved. 480708Sjake * 580708Sjake * Redistribution and use in source and binary forms, with or without 680708Sjake * modification, are permitted provided that the following conditions 780708Sjake * are met: 880708Sjake * 1. Redistributions of source code must retain the above copyright 980708Sjake * notice, this list of conditions and the following disclaimer. 1080708Sjake * 2. Redistributions in binary form must reproduce the above copyright 1180708Sjake * notice, this list of conditions and the following disclaimer in the 1280708Sjake * documentation and/or other materials provided with the distribution. 1380708Sjake * 1481334Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1580708Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1680708Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1781334Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1880708Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1980708Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2080708Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2180708Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2280708Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2380708Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2480708Sjake * SUCH DAMAGE. 2580708Sjake * 2680708Sjake * $FreeBSD: head/sys/sparc64/include/smp.h 169730 2007-05-19 05:01:43Z kan $ 2780708Sjake */ 2880708Sjake 2980708Sjake#ifndef _MACHINE_SMP_H_ 3080708Sjake#define _MACHINE_SMP_H_ 3180708Sjake 3291617Sjake#define CPU_CLKSYNC 1 3391617Sjake#define CPU_INIT 2 3491617Sjake#define CPU_BOOTSTRAP 3 3589051Sjake 3689051Sjake#ifndef LOCORE 3789051Sjake 3891157Sjake#include <machine/intr_machdep.h> 39169730Skan#include <machine/pcb.h> 4091617Sjake#include <machine/tte.h> 4191157Sjake 4289051Sjake#define IDR_BUSY (1<<0) 4389051Sjake#define IDR_NACK (1<<1) 4489051Sjake 4589051Sjake#define IPI_AST PIL_AST 4689051Sjake#define IPI_RENDEZVOUS PIL_RENDEZVOUS 4789051Sjake#define IPI_STOP PIL_STOP 4889051Sjake 49135943Skensmith#define IPI_RETRIES 5000 5089051Sjake 5189051Sjakestruct cpu_start_args { 5291783Sjake u_int csa_count; 5389051Sjake u_int csa_mid; 5489051Sjake u_int csa_state; 5591783Sjake vm_offset_t csa_pcpu; 5691617Sjake u_long csa_tick; 5791617Sjake u_long csa_ver; 5891617Sjake struct tte csa_ttes[PCPU_PAGES]; 5989051Sjake}; 6089051Sjake 6197001Sjakestruct ipi_cache_args { 6297001Sjake u_int ica_mask; 63113238Sjake vm_paddr_t ica_pa; 6497001Sjake}; 6597001Sjake 6689051Sjakestruct ipi_tlb_args { 6792199Sjake u_int ita_mask; 6891783Sjake struct pmap *ita_pmap; 6989051Sjake u_long ita_start; 7089051Sjake u_long ita_end; 7189051Sjake}; 7289051Sjake#define ita_va ita_start 7389051Sjake 7489051Sjakestruct pcpu; 7589051Sjake 76152022Sjhbextern struct pcb stoppcbs[]; 77152022Sjhb 7889051Sjakevoid cpu_mp_bootstrap(struct pcpu *pc); 7992199Sjakevoid cpu_mp_shutdown(void); 8089051Sjake 8189051Sjakevoid cpu_ipi_selected(u_int cpus, u_long d0, u_long d1, u_long d2); 8289051Sjakevoid cpu_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2); 8389051Sjake 8489051Sjakevoid ipi_selected(u_int cpus, u_int ipi); 8589051Sjakevoid ipi_all(u_int ipi); 8689051Sjakevoid ipi_all_but_self(u_int ipi); 8789051Sjake 8891617Sjakevm_offset_t mp_tramp_alloc(void); 8991617Sjake 90108187Sjakeextern struct mtx ipi_mtx; 91108187Sjakeextern struct ipi_cache_args ipi_cache_args; 92108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 9389051Sjake 9491617Sjakeextern vm_offset_t mp_tramp; 9591617Sjakeextern char *mp_tramp_code; 9691617Sjakeextern u_long mp_tramp_code_len; 9791617Sjakeextern u_long mp_tramp_tlb_slots; 9891617Sjakeextern u_long mp_tramp_func; 9991617Sjake 10091617Sjakeextern void mp_startup(void); 10191617Sjake 102112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 103112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 104112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 105112399Sjake 10689051Sjakeextern char tl_ipi_level[]; 10789051Sjakeextern char tl_ipi_tlb_context_demap[]; 10889051Sjakeextern char tl_ipi_tlb_page_demap[]; 10989051Sjakeextern char tl_ipi_tlb_range_demap[]; 11089051Sjake 11189051Sjake#ifdef SMP 11289051Sjake 113108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 114108187Sjake 11597001Sjakestatic __inline void * 116113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 11797001Sjake{ 11897001Sjake struct ipi_cache_args *ica; 11997001Sjake 12097001Sjake if (smp_cpus == 1) 12197001Sjake return (NULL); 12297001Sjake ica = &ipi_cache_args; 123108187Sjake mtx_lock_spin(&ipi_mtx); 12497001Sjake ica->ica_mask = all_cpus; 12597001Sjake ica->ica_pa = pa; 126112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 12797001Sjake return (&ica->ica_mask); 12897001Sjake} 12997001Sjake 13097001Sjakestatic __inline void * 131113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 13297001Sjake{ 13397001Sjake struct ipi_cache_args *ica; 13497001Sjake 13597001Sjake if (smp_cpus == 1) 13697001Sjake return (NULL); 13797001Sjake ica = &ipi_cache_args; 138108187Sjake mtx_lock_spin(&ipi_mtx); 13997001Sjake ica->ica_mask = all_cpus; 14097001Sjake ica->ica_pa = pa; 141112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 14297001Sjake return (&ica->ica_mask); 14397001Sjake} 14497001Sjake 14589051Sjakestatic __inline void * 14691783Sjakeipi_tlb_context_demap(struct pmap *pm) 14789051Sjake{ 14889051Sjake struct ipi_tlb_args *ita; 14991783Sjake u_int cpus; 15089051Sjake 15191783Sjake if (smp_cpus == 1) 15289051Sjake return (NULL); 15391783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 15491783Sjake return (NULL); 15589051Sjake ita = &ipi_tlb_args; 156108187Sjake mtx_lock_spin(&ipi_mtx); 15792199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 15891783Sjake ita->ita_pmap = pm; 15991783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 16091783Sjake (u_long)ita); 16192199Sjake return (&ita->ita_mask); 16289051Sjake} 16389051Sjake 16489051Sjakestatic __inline void * 165100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 16689051Sjake{ 16789051Sjake struct ipi_tlb_args *ita; 16891783Sjake u_int cpus; 16989051Sjake 17091783Sjake if (smp_cpus == 1) 17189051Sjake return (NULL); 17291783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 17391783Sjake return (NULL); 17489051Sjake ita = &ipi_tlb_args; 175108187Sjake mtx_lock_spin(&ipi_mtx); 17692199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 17791783Sjake ita->ita_pmap = pm; 17889051Sjake ita->ita_va = va; 17991783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 18092199Sjake return (&ita->ita_mask); 18189051Sjake} 18289051Sjake 18389051Sjakestatic __inline void * 18491783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 18589051Sjake{ 18689051Sjake struct ipi_tlb_args *ita; 18791783Sjake u_int cpus; 18889051Sjake 18991783Sjake if (smp_cpus == 1) 19089051Sjake return (NULL); 19191783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 19291783Sjake return (NULL); 19389051Sjake ita = &ipi_tlb_args; 194108187Sjake mtx_lock_spin(&ipi_mtx); 19592199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 19691783Sjake ita->ita_pmap = pm; 19789051Sjake ita->ita_start = start; 19889051Sjake ita->ita_end = end; 19991783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 20092199Sjake return (&ita->ita_mask); 20189051Sjake} 20289051Sjake 20389051Sjakestatic __inline void 20489051Sjakeipi_wait(void *cookie) 20589051Sjake{ 206143190Salc volatile u_int *mask; 20789051Sjake 20892199Sjake if ((mask = cookie) != NULL) { 20992199Sjake atomic_clear_int(mask, PCPU_GET(cpumask)); 21092199Sjake while (*mask != 0) 21191617Sjake ; 212108187Sjake mtx_unlock_spin(&ipi_mtx); 21389051Sjake } 21489051Sjake} 21589051Sjake 216108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 21791783Sjake 21889051Sjake#else 21989051Sjake 22089051Sjakestatic __inline void * 221113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 22297001Sjake{ 22397001Sjake return (NULL); 22497001Sjake} 22597001Sjake 22697001Sjakestatic __inline void * 227113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 22897001Sjake{ 22997001Sjake return (NULL); 23097001Sjake} 23197001Sjake 23297001Sjakestatic __inline void * 23391783Sjakeipi_tlb_context_demap(struct pmap *pm) 23489051Sjake{ 23589051Sjake return (NULL); 23689051Sjake} 23789051Sjake 23889051Sjakestatic __inline void * 239100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 24089051Sjake{ 24189051Sjake return (NULL); 24289051Sjake} 24389051Sjake 24489051Sjakestatic __inline void * 24591783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 24689051Sjake{ 24789051Sjake return (NULL); 24889051Sjake} 24989051Sjake 25089051Sjakestatic __inline void 25189051Sjakeipi_wait(void *cookie) 25289051Sjake{ 25389051Sjake} 25489051Sjake 25589051Sjake#endif /* SMP */ 25689051Sjake 25789051Sjake#endif /* !LOCORE */ 25889051Sjake 25980708Sjake#endif /* !_MACHINE_SMP_H_ */ 260