smp.h revision 182730
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 182730 2008-09-03 17:39:19Z marius $ 2780708Sjake */ 2880708Sjake 2980708Sjake#ifndef _MACHINE_SMP_H_ 3080708Sjake#define _MACHINE_SMP_H_ 3180708Sjake 32182730Smarius#define CPU_TICKSYNC 1 33182730Smarius#define CPU_STICKSYNC 2 34182730Smarius#define CPU_INIT 3 35182730Smarius#define CPU_BOOTSTRAP 4 3689051Sjake 3789051Sjake#ifndef LOCORE 3889051Sjake 3991157Sjake#include <machine/intr_machdep.h> 40169730Skan#include <machine/pcb.h> 4191617Sjake#include <machine/tte.h> 4291157Sjake 43170846Smarius#define IDR_BUSY 0x0000000000000001ULL 44170846Smarius#define IDR_NACK 0x0000000000000002ULL 45170846Smarius#define IDR_CHEETAH_ALL_BUSY 0x5555555555555555ULL 46170846Smarius#define IDR_CHEETAH_ALL_NACK (~IDR_CHEETAH_ALL_BUSY) 47170846Smarius#define IDR_CHEETAH_MAX_BN_PAIRS 32 48170846Smarius#define IDR_JALAPENO_MAX_BN_PAIRS 4 4989051Sjake 50169796Smarius#define IDC_ITID_SHIFT 14 51170846Smarius#define IDC_BN_SHIFT 24 52169796Smarius 5389051Sjake#define IPI_AST PIL_AST 5489051Sjake#define IPI_RENDEZVOUS PIL_RENDEZVOUS 55178048Smarius#define IPI_PREEMPT PIL_PREEMPT 5689051Sjake#define IPI_STOP PIL_STOP 5789051Sjake 58135943Skensmith#define IPI_RETRIES 5000 5989051Sjake 6089051Sjakestruct cpu_start_args { 6191783Sjake u_int csa_count; 6289051Sjake u_int csa_mid; 6389051Sjake u_int csa_state; 6491783Sjake vm_offset_t csa_pcpu; 6591617Sjake u_long csa_tick; 66182730Smarius u_long csa_stick; 6791617Sjake u_long csa_ver; 6891617Sjake struct tte csa_ttes[PCPU_PAGES]; 6989051Sjake}; 7089051Sjake 7197001Sjakestruct ipi_cache_args { 7297001Sjake u_int ica_mask; 73113238Sjake vm_paddr_t ica_pa; 7497001Sjake}; 7597001Sjake 7689051Sjakestruct ipi_tlb_args { 7792199Sjake u_int ita_mask; 7891783Sjake struct pmap *ita_pmap; 7989051Sjake u_long ita_start; 8089051Sjake u_long ita_end; 8189051Sjake}; 8289051Sjake#define ita_va ita_start 8389051Sjake 8489051Sjakestruct pcpu; 8589051Sjake 86152022Sjhbextern struct pcb stoppcbs[]; 87152022Sjhb 8889051Sjakevoid cpu_mp_bootstrap(struct pcpu *pc); 8992199Sjakevoid cpu_mp_shutdown(void); 9089051Sjake 91170846Smariustypedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long); 92170846Smariusextern cpu_ipi_selected_t *cpu_ipi_selected; 9389051Sjake 9489051Sjakevoid ipi_selected(u_int cpus, u_int ipi); 9589051Sjakevoid ipi_all(u_int ipi); 9689051Sjakevoid ipi_all_but_self(u_int ipi); 9789051Sjake 98170846Smariusvoid mp_init(void); 9991617Sjake 100108187Sjakeextern struct mtx ipi_mtx; 101108187Sjakeextern struct ipi_cache_args ipi_cache_args; 102108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 10389051Sjake 10491617Sjakeextern char *mp_tramp_code; 10591617Sjakeextern u_long mp_tramp_code_len; 10691617Sjakeextern u_long mp_tramp_tlb_slots; 10791617Sjakeextern u_long mp_tramp_func; 10891617Sjake 10991617Sjakeextern void mp_startup(void); 11091617Sjake 111112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 112112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 113112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 114112399Sjake 11589051Sjakeextern char tl_ipi_level[]; 11689051Sjakeextern char tl_ipi_tlb_context_demap[]; 11789051Sjakeextern char tl_ipi_tlb_page_demap[]; 11889051Sjakeextern char tl_ipi_tlb_range_demap[]; 11989051Sjake 12089051Sjake#ifdef SMP 12189051Sjake 122108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 123108187Sjake 12497001Sjakestatic __inline void * 125113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 12697001Sjake{ 12797001Sjake struct ipi_cache_args *ica; 12897001Sjake 12997001Sjake if (smp_cpus == 1) 13097001Sjake return (NULL); 13197001Sjake ica = &ipi_cache_args; 132108187Sjake mtx_lock_spin(&ipi_mtx); 13397001Sjake ica->ica_mask = all_cpus; 13497001Sjake ica->ica_pa = pa; 135112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 13697001Sjake return (&ica->ica_mask); 13797001Sjake} 13897001Sjake 13997001Sjakestatic __inline void * 140113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 14197001Sjake{ 14297001Sjake struct ipi_cache_args *ica; 14397001Sjake 14497001Sjake if (smp_cpus == 1) 14597001Sjake return (NULL); 14697001Sjake ica = &ipi_cache_args; 147108187Sjake mtx_lock_spin(&ipi_mtx); 14897001Sjake ica->ica_mask = all_cpus; 14997001Sjake ica->ica_pa = pa; 150112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 15197001Sjake return (&ica->ica_mask); 15297001Sjake} 15397001Sjake 15489051Sjakestatic __inline void * 15591783Sjakeipi_tlb_context_demap(struct pmap *pm) 15689051Sjake{ 15789051Sjake struct ipi_tlb_args *ita; 15891783Sjake u_int cpus; 15989051Sjake 16091783Sjake if (smp_cpus == 1) 16189051Sjake return (NULL); 16291783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 16391783Sjake return (NULL); 16489051Sjake ita = &ipi_tlb_args; 165108187Sjake mtx_lock_spin(&ipi_mtx); 16692199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 16791783Sjake ita->ita_pmap = pm; 16891783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 16991783Sjake (u_long)ita); 17092199Sjake return (&ita->ita_mask); 17189051Sjake} 17289051Sjake 17389051Sjakestatic __inline void * 174100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 17589051Sjake{ 17689051Sjake struct ipi_tlb_args *ita; 17791783Sjake u_int cpus; 17889051Sjake 17991783Sjake if (smp_cpus == 1) 18089051Sjake return (NULL); 18191783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 18291783Sjake return (NULL); 18389051Sjake ita = &ipi_tlb_args; 184108187Sjake mtx_lock_spin(&ipi_mtx); 18592199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 18691783Sjake ita->ita_pmap = pm; 18789051Sjake ita->ita_va = va; 18891783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 18992199Sjake return (&ita->ita_mask); 19089051Sjake} 19189051Sjake 19289051Sjakestatic __inline void * 19391783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 19489051Sjake{ 19589051Sjake struct ipi_tlb_args *ita; 19691783Sjake u_int cpus; 19789051Sjake 19891783Sjake if (smp_cpus == 1) 19989051Sjake return (NULL); 20091783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 20191783Sjake return (NULL); 20289051Sjake ita = &ipi_tlb_args; 203108187Sjake mtx_lock_spin(&ipi_mtx); 20492199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 20591783Sjake ita->ita_pmap = pm; 20689051Sjake ita->ita_start = start; 20789051Sjake ita->ita_end = end; 20891783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 20992199Sjake return (&ita->ita_mask); 21089051Sjake} 21189051Sjake 21289051Sjakestatic __inline void 21389051Sjakeipi_wait(void *cookie) 21489051Sjake{ 215143190Salc volatile u_int *mask; 21689051Sjake 21792199Sjake if ((mask = cookie) != NULL) { 21892199Sjake atomic_clear_int(mask, PCPU_GET(cpumask)); 21992199Sjake while (*mask != 0) 22091617Sjake ; 221108187Sjake mtx_unlock_spin(&ipi_mtx); 22289051Sjake } 22389051Sjake} 22489051Sjake 225108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 22691783Sjake 22789051Sjake#else 22889051Sjake 22989051Sjakestatic __inline void * 230113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 23197001Sjake{ 232169796Smarius 23397001Sjake return (NULL); 23497001Sjake} 23597001Sjake 23697001Sjakestatic __inline void * 237113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 23897001Sjake{ 239169796Smarius 24097001Sjake return (NULL); 24197001Sjake} 24297001Sjake 24397001Sjakestatic __inline void * 24491783Sjakeipi_tlb_context_demap(struct pmap *pm) 24589051Sjake{ 246169796Smarius 24789051Sjake return (NULL); 24889051Sjake} 24989051Sjake 25089051Sjakestatic __inline void * 251100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 25289051Sjake{ 253169796Smarius 25489051Sjake return (NULL); 25589051Sjake} 25689051Sjake 25789051Sjakestatic __inline void * 25891783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 25989051Sjake{ 260169796Smarius 26189051Sjake return (NULL); 26289051Sjake} 26389051Sjake 26489051Sjakestatic __inline void 26589051Sjakeipi_wait(void *cookie) 26689051Sjake{ 267169796Smarius 26889051Sjake} 26989051Sjake 27089051Sjake#endif /* SMP */ 27189051Sjake 27289051Sjake#endif /* !LOCORE */ 27389051Sjake 27480708Sjake#endif /* !_MACHINE_SMP_H_ */ 275