smp.h revision 239864
180708Sjake/*- 280708Sjake * Copyright (c) 2001 Jake Burkholder. 3223126Smarius * Copyright (c) 2007 - 2011 Marius Strobl <marius@FreeBSD.org> 480708Sjake * All rights reserved. 580708Sjake * 680708Sjake * Redistribution and use in source and binary forms, with or without 780708Sjake * modification, are permitted provided that the following conditions 880708Sjake * are met: 980708Sjake * 1. Redistributions of source code must retain the above copyright 1080708Sjake * notice, this list of conditions and the following disclaimer. 1180708Sjake * 2. Redistributions in binary form must reproduce the above copyright 1280708Sjake * notice, this list of conditions and the following disclaimer in the 1380708Sjake * documentation and/or other materials provided with the distribution. 1480708Sjake * 1581334Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1680708Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1780708Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1881334Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1980708Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2080708Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2180708Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2280708Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2380708Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2480708Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2580708Sjake * SUCH DAMAGE. 2680708Sjake * 2780708Sjake * $FreeBSD: head/sys/sparc64/include/smp.h 239864 2012-08-29 16:56:50Z marius $ 2880708Sjake */ 2980708Sjake 3080708Sjake#ifndef _MACHINE_SMP_H_ 3180708Sjake#define _MACHINE_SMP_H_ 3280708Sjake 33183142Smarius#ifdef SMP 34183142Smarius 35182730Smarius#define CPU_TICKSYNC 1 36182730Smarius#define CPU_STICKSYNC 2 37182730Smarius#define CPU_INIT 3 38182730Smarius#define CPU_BOOTSTRAP 4 3989051Sjake 4089051Sjake#ifndef LOCORE 4189051Sjake 42222813Sattilio#include <sys/cpuset.h> 43209695Smarius#include <sys/proc.h> 44209695Smarius#include <sys/sched.h> 45209695Smarius 4691157Sjake#include <machine/intr_machdep.h> 47169730Skan#include <machine/pcb.h> 4891617Sjake#include <machine/tte.h> 4991157Sjake 50170846Smarius#define IDR_BUSY 0x0000000000000001ULL 51170846Smarius#define IDR_NACK 0x0000000000000002ULL 52170846Smarius#define IDR_CHEETAH_ALL_BUSY 0x5555555555555555ULL 53170846Smarius#define IDR_CHEETAH_ALL_NACK (~IDR_CHEETAH_ALL_BUSY) 54170846Smarius#define IDR_CHEETAH_MAX_BN_PAIRS 32 55170846Smarius#define IDR_JALAPENO_MAX_BN_PAIRS 4 5689051Sjake 57169796Smarius#define IDC_ITID_SHIFT 14 58170846Smarius#define IDC_BN_SHIFT 24 59169796Smarius 6089051Sjake#define IPI_AST PIL_AST 6189051Sjake#define IPI_RENDEZVOUS PIL_RENDEZVOUS 62178048Smarius#define IPI_PREEMPT PIL_PREEMPT 63210601Smav#define IPI_HARDCLOCK PIL_HARDCLOCK 6489051Sjake#define IPI_STOP PIL_STOP 65196196Sattilio#define IPI_STOP_HARD PIL_STOP 6689051Sjake 67135943Skensmith#define IPI_RETRIES 5000 6889051Sjake 6989051Sjakestruct cpu_start_args { 7091783Sjake u_int csa_count; 7189051Sjake u_int csa_mid; 7289051Sjake u_int csa_state; 7391783Sjake vm_offset_t csa_pcpu; 7491617Sjake u_long csa_tick; 75182730Smarius u_long csa_stick; 7691617Sjake u_long csa_ver; 7791617Sjake struct tte csa_ttes[PCPU_PAGES]; 7889051Sjake}; 7989051Sjake 8097001Sjakestruct ipi_cache_args { 81222813Sattilio cpuset_t ica_mask; 82113238Sjake vm_paddr_t ica_pa; 8397001Sjake}; 8497001Sjake 85211071Smariusstruct ipi_rd_args { 86222813Sattilio cpuset_t ira_mask; 87211071Smarius register_t *ira_val; 88211071Smarius}; 89211071Smarius 9089051Sjakestruct ipi_tlb_args { 91222813Sattilio cpuset_t ita_mask; 9291783Sjake struct pmap *ita_pmap; 9389051Sjake u_long ita_start; 9489051Sjake u_long ita_end; 9589051Sjake}; 9689051Sjake#define ita_va ita_start 9789051Sjake 9889051Sjakestruct pcpu; 9989051Sjake 100152022Sjhbextern struct pcb stoppcbs[]; 101152022Sjhb 10289051Sjakevoid cpu_mp_bootstrap(struct pcpu *pc); 10392199Sjakevoid cpu_mp_shutdown(void); 10489051Sjake 105222813Sattiliotypedef void cpu_ipi_selected_t(cpuset_t, u_long, u_long, u_long); 106170846Smariusextern cpu_ipi_selected_t *cpu_ipi_selected; 107211050Smariustypedef void cpu_ipi_single_t(u_int, u_long, u_long, u_long); 108211050Smariusextern cpu_ipi_single_t *cpu_ipi_single; 10989051Sjake 110204152Smariusvoid mp_init(u_int cpu_impl); 11191617Sjake 112108187Sjakeextern struct ipi_cache_args ipi_cache_args; 113211071Smariusextern struct ipi_rd_args ipi_rd_args; 114108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 11589051Sjake 11691617Sjakeextern char *mp_tramp_code; 11791617Sjakeextern u_long mp_tramp_code_len; 11891617Sjakeextern u_long mp_tramp_tlb_slots; 11991617Sjakeextern u_long mp_tramp_func; 12091617Sjake 12191617Sjakeextern void mp_startup(void); 12291617Sjake 123112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 124112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 125112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 126112399Sjake 12789051Sjakeextern char tl_ipi_level[]; 128211071Smarius 129211071Smariusextern char tl_ipi_stick_rd[]; 130211071Smariusextern char tl_ipi_tick_rd[]; 131211071Smarius 13289051Sjakeextern char tl_ipi_tlb_context_demap[]; 13389051Sjakeextern char tl_ipi_tlb_page_demap[]; 13489051Sjakeextern char tl_ipi_tlb_range_demap[]; 13589051Sjake 136183142Smariusstatic __inline void 137183142Smariusipi_all_but_self(u_int ipi) 138183142Smarius{ 139223126Smarius cpuset_t cpus; 14089051Sjake 141223126Smarius cpus = all_cpus; 142223126Smarius CPU_CLR(PCPU_GET(cpuid), &cpus); 143223126Smarius cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); 144183142Smarius} 145183142Smarius 146183142Smariusstatic __inline void 147222813Sattilioipi_selected(cpuset_t cpus, u_int ipi) 148183142Smarius{ 149183142Smarius 150183142Smarius cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); 151183142Smarius} 152183142Smarius 153210939Sjhbstatic __inline void 154210939Sjhbipi_cpu(int cpu, u_int ipi) 155210939Sjhb{ 156210939Sjhb 157211050Smarius cpu_ipi_single(cpu, 0, (u_long)tl_ipi_level, ipi); 158210939Sjhb} 159210939Sjhb 160108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 161108187Sjake 16297001Sjakestatic __inline void * 163113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 16497001Sjake{ 16597001Sjake struct ipi_cache_args *ica; 16697001Sjake 16797001Sjake if (smp_cpus == 1) 16897001Sjake return (NULL); 169209695Smarius sched_pin(); 17097001Sjake ica = &ipi_cache_args; 171239864Smarius mtx_lock_spin(&smp_ipi_mtx); 17297001Sjake ica->ica_mask = all_cpus; 173223126Smarius CPU_CLR(PCPU_GET(cpuid), &ica->ica_mask); 17497001Sjake ica->ica_pa = pa; 175223126Smarius cpu_ipi_selected(ica->ica_mask, 0, (u_long)func, (u_long)ica); 17697001Sjake return (&ica->ica_mask); 17797001Sjake} 17897001Sjake 17997001Sjakestatic __inline void * 180113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 18197001Sjake{ 18297001Sjake struct ipi_cache_args *ica; 18397001Sjake 18497001Sjake if (smp_cpus == 1) 18597001Sjake return (NULL); 186209695Smarius sched_pin(); 18797001Sjake ica = &ipi_cache_args; 188239864Smarius mtx_lock_spin(&smp_ipi_mtx); 18997001Sjake ica->ica_mask = all_cpus; 190223126Smarius CPU_CLR(PCPU_GET(cpuid), &ica->ica_mask); 19197001Sjake ica->ica_pa = pa; 192223126Smarius cpu_ipi_selected(ica->ica_mask, 0, (u_long)func, (u_long)ica); 19397001Sjake return (&ica->ica_mask); 19497001Sjake} 19597001Sjake 19689051Sjakestatic __inline void * 197211071Smariusipi_rd(u_int cpu, void *func, u_long *val) 198211071Smarius{ 199211071Smarius struct ipi_rd_args *ira; 200211071Smarius 201211071Smarius if (smp_cpus == 1) 202211071Smarius return (NULL); 203211071Smarius sched_pin(); 204211071Smarius ira = &ipi_rd_args; 205223126Smarius CPU_SETOF(cpu, &ira->ira_mask); 206211071Smarius ira->ira_val = val; 207211071Smarius cpu_ipi_single(cpu, 0, (u_long)func, (u_long)ira); 208211071Smarius return (&ira->ira_mask); 209211071Smarius} 210211071Smarius 211211071Smariusstatic __inline void * 21291783Sjakeipi_tlb_context_demap(struct pmap *pm) 21389051Sjake{ 21489051Sjake struct ipi_tlb_args *ita; 215222813Sattilio cpuset_t cpus; 21689051Sjake 21791783Sjake if (smp_cpus == 1) 21889051Sjake return (NULL); 219209695Smarius sched_pin(); 220222813Sattilio cpus = pm->pm_active; 221223126Smarius CPU_AND(&cpus, &all_cpus); 222223126Smarius CPU_CLR(PCPU_GET(cpuid), &cpus); 223222813Sattilio if (CPU_EMPTY(&cpus)) { 224209695Smarius sched_unpin(); 22591783Sjake return (NULL); 226209695Smarius } 22789051Sjake ita = &ipi_tlb_args; 228239864Smarius mtx_lock_spin(&smp_ipi_mtx); 229222813Sattilio ita->ita_mask = cpus; 23091783Sjake ita->ita_pmap = pm; 23191783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 23291783Sjake (u_long)ita); 23392199Sjake return (&ita->ita_mask); 23489051Sjake} 23589051Sjake 23689051Sjakestatic __inline void * 237100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 23889051Sjake{ 23989051Sjake struct ipi_tlb_args *ita; 240222813Sattilio cpuset_t cpus; 24189051Sjake 24291783Sjake if (smp_cpus == 1) 24389051Sjake return (NULL); 244209695Smarius sched_pin(); 245222813Sattilio cpus = pm->pm_active; 246223126Smarius CPU_AND(&cpus, &all_cpus); 247223126Smarius CPU_CLR(PCPU_GET(cpuid), &cpus); 248222813Sattilio if (CPU_EMPTY(&cpus)) { 249209695Smarius sched_unpin(); 25091783Sjake return (NULL); 251209695Smarius } 25289051Sjake ita = &ipi_tlb_args; 253239864Smarius mtx_lock_spin(&smp_ipi_mtx); 254222813Sattilio ita->ita_mask = cpus; 25591783Sjake ita->ita_pmap = pm; 25689051Sjake ita->ita_va = va; 25791783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 25892199Sjake return (&ita->ita_mask); 25989051Sjake} 26089051Sjake 26189051Sjakestatic __inline void * 26291783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 26389051Sjake{ 26489051Sjake struct ipi_tlb_args *ita; 265222813Sattilio cpuset_t cpus; 26689051Sjake 26791783Sjake if (smp_cpus == 1) 26889051Sjake return (NULL); 269209695Smarius sched_pin(); 270222813Sattilio cpus = pm->pm_active; 271223126Smarius CPU_AND(&cpus, &all_cpus); 272223126Smarius CPU_CLR(PCPU_GET(cpuid), &cpus); 273222813Sattilio if (CPU_EMPTY(&cpus)) { 274209695Smarius sched_unpin(); 27591783Sjake return (NULL); 276209695Smarius } 27789051Sjake ita = &ipi_tlb_args; 278239864Smarius mtx_lock_spin(&smp_ipi_mtx); 279222813Sattilio ita->ita_mask = cpus; 28091783Sjake ita->ita_pmap = pm; 28189051Sjake ita->ita_start = start; 28289051Sjake ita->ita_end = end; 283211050Smarius cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, 284211050Smarius (u_long)ita); 28592199Sjake return (&ita->ita_mask); 28689051Sjake} 28789051Sjake 28889051Sjakestatic __inline void 28989051Sjakeipi_wait(void *cookie) 29089051Sjake{ 291222813Sattilio volatile cpuset_t *mask; 29289051Sjake 29392199Sjake if ((mask = cookie) != NULL) { 294222813Sattilio while (!CPU_EMPTY(mask)) 29591617Sjake ; 296239864Smarius mtx_unlock_spin(&smp_ipi_mtx); 297209695Smarius sched_unpin(); 29889051Sjake } 29989051Sjake} 30089051Sjake 301239864Smariusstatic __inline void 302239864Smariusipi_wait_unlocked(void *cookie) 303239864Smarius{ 304239864Smarius volatile cpuset_t *mask; 305239864Smarius 306239864Smarius if ((mask = cookie) != NULL) { 307239864Smarius while (!CPU_EMPTY(mask)) 308239864Smarius ; 309239864Smarius sched_unpin(); 310239864Smarius } 311239864Smarius} 312239864Smarius 313108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 31491783Sjake 315183142Smarius#endif /* !LOCORE */ 316183142Smarius 31789051Sjake#else 31889051Sjake 319183142Smarius#ifndef LOCORE 320183142Smarius 32189051Sjakestatic __inline void * 322209695Smariusipi_dcache_page_inval(void *func __unused, vm_paddr_t pa __unused) 32397001Sjake{ 324169796Smarius 32597001Sjake return (NULL); 32697001Sjake} 32797001Sjake 32897001Sjakestatic __inline void * 329209695Smariusipi_icache_page_inval(void *func __unused, vm_paddr_t pa __unused) 33097001Sjake{ 331169796Smarius 33297001Sjake return (NULL); 33397001Sjake} 33497001Sjake 33597001Sjakestatic __inline void * 336211071Smariusipi_rd(u_int cpu __unused, void *func __unused, u_long *val __unused) 337211071Smarius{ 338211071Smarius 339211071Smarius return (NULL); 340211071Smarius} 341211071Smarius 342211071Smariusstatic __inline void * 343209695Smariusipi_tlb_context_demap(struct pmap *pm __unused) 34489051Sjake{ 345169796Smarius 34689051Sjake return (NULL); 34789051Sjake} 34889051Sjake 34989051Sjakestatic __inline void * 350209695Smariusipi_tlb_page_demap(struct pmap *pm __unused, vm_offset_t va __unused) 35189051Sjake{ 352169796Smarius 35389051Sjake return (NULL); 35489051Sjake} 35589051Sjake 35689051Sjakestatic __inline void * 357209695Smariusipi_tlb_range_demap(struct pmap *pm __unused, vm_offset_t start __unused, 358209695Smarius __unused vm_offset_t end) 35989051Sjake{ 360169796Smarius 36189051Sjake return (NULL); 36289051Sjake} 36389051Sjake 36489051Sjakestatic __inline void 365239864Smariusipi_wait(void *cookie __unused) 36689051Sjake{ 367169796Smarius 36889051Sjake} 36989051Sjake 370183142Smariusstatic __inline void 371239864Smariusipi_wait_unlocked(void *cookie __unused) 372239864Smarius{ 373239864Smarius 374239864Smarius} 375239864Smarius 376239864Smariusstatic __inline void 377183142Smariustl_ipi_cheetah_dcache_page_inval(void) 378183142Smarius{ 37989051Sjake 380183142Smarius} 381183142Smarius 382183142Smariusstatic __inline void 383183142Smariustl_ipi_spitfire_dcache_page_inval(void) 384183142Smarius{ 385183142Smarius 386183142Smarius} 387183142Smarius 388183142Smariusstatic __inline void 389183142Smariustl_ipi_spitfire_icache_page_inval(void) 390183142Smarius{ 391183142Smarius 392183142Smarius} 393183142Smarius 39489051Sjake#endif /* !LOCORE */ 39589051Sjake 396183142Smarius#endif /* SMP */ 397183142Smarius 39880708Sjake#endif /* !_MACHINE_SMP_H_ */ 399