smp.h revision 210939
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 210939 2010-08-06 15:36:59Z jhb $ 2780708Sjake */ 2880708Sjake 2980708Sjake#ifndef _MACHINE_SMP_H_ 3080708Sjake#define _MACHINE_SMP_H_ 3180708Sjake 32183142Smarius#ifdef SMP 33183142Smarius 34182730Smarius#define CPU_TICKSYNC 1 35182730Smarius#define CPU_STICKSYNC 2 36182730Smarius#define CPU_INIT 3 37182730Smarius#define CPU_BOOTSTRAP 4 3889051Sjake 3989051Sjake#ifndef LOCORE 4089051Sjake 41209695Smarius#include <sys/proc.h> 42209695Smarius#include <sys/sched.h> 43209695Smarius 4491157Sjake#include <machine/intr_machdep.h> 45169730Skan#include <machine/pcb.h> 4691617Sjake#include <machine/tte.h> 4791157Sjake 48170846Smarius#define IDR_BUSY 0x0000000000000001ULL 49170846Smarius#define IDR_NACK 0x0000000000000002ULL 50170846Smarius#define IDR_CHEETAH_ALL_BUSY 0x5555555555555555ULL 51170846Smarius#define IDR_CHEETAH_ALL_NACK (~IDR_CHEETAH_ALL_BUSY) 52170846Smarius#define IDR_CHEETAH_MAX_BN_PAIRS 32 53170846Smarius#define IDR_JALAPENO_MAX_BN_PAIRS 4 5489051Sjake 55169796Smarius#define IDC_ITID_SHIFT 14 56170846Smarius#define IDC_BN_SHIFT 24 57169796Smarius 5889051Sjake#define IPI_AST PIL_AST 5989051Sjake#define IPI_RENDEZVOUS PIL_RENDEZVOUS 60178048Smarius#define IPI_PREEMPT PIL_PREEMPT 61210601Smav#define IPI_HARDCLOCK PIL_HARDCLOCK 62210601Smav#define IPI_STATCLOCK PIL_STATCLOCK 6389051Sjake#define IPI_STOP PIL_STOP 64196196Sattilio#define IPI_STOP_HARD PIL_STOP 6589051Sjake 66135943Skensmith#define IPI_RETRIES 5000 6789051Sjake 6889051Sjakestruct cpu_start_args { 6991783Sjake u_int csa_count; 7089051Sjake u_int csa_mid; 7189051Sjake u_int csa_state; 7291783Sjake vm_offset_t csa_pcpu; 7391617Sjake u_long csa_tick; 74182730Smarius u_long csa_stick; 7591617Sjake u_long csa_ver; 7691617Sjake struct tte csa_ttes[PCPU_PAGES]; 7789051Sjake}; 7889051Sjake 7997001Sjakestruct ipi_cache_args { 8097001Sjake u_int ica_mask; 81113238Sjake vm_paddr_t ica_pa; 8297001Sjake}; 8397001Sjake 8489051Sjakestruct ipi_tlb_args { 8592199Sjake u_int ita_mask; 8691783Sjake struct pmap *ita_pmap; 8789051Sjake u_long ita_start; 8889051Sjake u_long ita_end; 8989051Sjake}; 9089051Sjake#define ita_va ita_start 9189051Sjake 9289051Sjakestruct pcpu; 9389051Sjake 94152022Sjhbextern struct pcb stoppcbs[]; 95152022Sjhb 9689051Sjakevoid cpu_mp_bootstrap(struct pcpu *pc); 9792199Sjakevoid cpu_mp_shutdown(void); 9889051Sjake 99170846Smariustypedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long); 100170846Smariusextern cpu_ipi_selected_t *cpu_ipi_selected; 10189051Sjake 102204152Smariusvoid mp_init(u_int cpu_impl); 10391617Sjake 104108187Sjakeextern struct mtx ipi_mtx; 105108187Sjakeextern struct ipi_cache_args ipi_cache_args; 106108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 10789051Sjake 10891617Sjakeextern char *mp_tramp_code; 10991617Sjakeextern u_long mp_tramp_code_len; 11091617Sjakeextern u_long mp_tramp_tlb_slots; 11191617Sjakeextern u_long mp_tramp_func; 11291617Sjake 11391617Sjakeextern void mp_startup(void); 11491617Sjake 115112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 116112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 117112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 118112399Sjake 11989051Sjakeextern char tl_ipi_level[]; 12089051Sjakeextern char tl_ipi_tlb_context_demap[]; 12189051Sjakeextern char tl_ipi_tlb_page_demap[]; 12289051Sjakeextern char tl_ipi_tlb_range_demap[]; 12389051Sjake 124183142Smariusstatic __inline void 125183142Smariusipi_all_but_self(u_int ipi) 126183142Smarius{ 12789051Sjake 128183142Smarius cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi); 129183142Smarius} 130183142Smarius 131183142Smariusstatic __inline void 132183142Smariusipi_selected(u_int cpus, u_int ipi) 133183142Smarius{ 134183142Smarius 135183142Smarius cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); 136183142Smarius} 137183142Smarius 138210939Sjhbstatic __inline void 139210939Sjhbipi_cpu(int cpu, u_int ipi) 140210939Sjhb{ 141210939Sjhb 142210939Sjhb /* 143210939Sjhb * XXX: Not ideal, but would require more work to add a cpu_ipi_cpu 144210939Sjhb * function pointer. 145210939Sjhb */ 146210939Sjhb cpu_ipi_selected(1 << cpu, 0, (u_long)tl_ipi_level, ipi); 147210939Sjhb} 148210939Sjhb 149108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 150108187Sjake 15197001Sjakestatic __inline void * 152113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 15397001Sjake{ 15497001Sjake struct ipi_cache_args *ica; 15597001Sjake 15697001Sjake if (smp_cpus == 1) 15797001Sjake return (NULL); 158209695Smarius sched_pin(); 15997001Sjake ica = &ipi_cache_args; 160108187Sjake mtx_lock_spin(&ipi_mtx); 16197001Sjake ica->ica_mask = all_cpus; 16297001Sjake ica->ica_pa = pa; 163112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 16497001Sjake return (&ica->ica_mask); 16597001Sjake} 16697001Sjake 16797001Sjakestatic __inline void * 168113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 16997001Sjake{ 17097001Sjake struct ipi_cache_args *ica; 17197001Sjake 17297001Sjake if (smp_cpus == 1) 17397001Sjake return (NULL); 174209695Smarius sched_pin(); 17597001Sjake ica = &ipi_cache_args; 176108187Sjake mtx_lock_spin(&ipi_mtx); 17797001Sjake ica->ica_mask = all_cpus; 17897001Sjake ica->ica_pa = pa; 179112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 18097001Sjake return (&ica->ica_mask); 18197001Sjake} 18297001Sjake 18389051Sjakestatic __inline void * 18491783Sjakeipi_tlb_context_demap(struct pmap *pm) 18589051Sjake{ 18689051Sjake struct ipi_tlb_args *ita; 18791783Sjake u_int cpus; 18889051Sjake 18991783Sjake if (smp_cpus == 1) 19089051Sjake return (NULL); 191209695Smarius sched_pin(); 192209695Smarius if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) { 193209695Smarius sched_unpin(); 19491783Sjake return (NULL); 195209695Smarius } 19689051Sjake ita = &ipi_tlb_args; 197108187Sjake mtx_lock_spin(&ipi_mtx); 19892199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 19991783Sjake ita->ita_pmap = pm; 20091783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 20191783Sjake (u_long)ita); 20292199Sjake return (&ita->ita_mask); 20389051Sjake} 20489051Sjake 20589051Sjakestatic __inline void * 206100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 20789051Sjake{ 20889051Sjake struct ipi_tlb_args *ita; 20991783Sjake u_int cpus; 21089051Sjake 21191783Sjake if (smp_cpus == 1) 21289051Sjake return (NULL); 213209695Smarius sched_pin(); 214209695Smarius if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) { 215209695Smarius sched_unpin(); 21691783Sjake return (NULL); 217209695Smarius } 21889051Sjake ita = &ipi_tlb_args; 219108187Sjake mtx_lock_spin(&ipi_mtx); 22092199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 22191783Sjake ita->ita_pmap = pm; 22289051Sjake ita->ita_va = va; 22391783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 22492199Sjake return (&ita->ita_mask); 22589051Sjake} 22689051Sjake 22789051Sjakestatic __inline void * 22891783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 22989051Sjake{ 23089051Sjake struct ipi_tlb_args *ita; 23191783Sjake u_int cpus; 23289051Sjake 23391783Sjake if (smp_cpus == 1) 23489051Sjake return (NULL); 235209695Smarius sched_pin(); 236209695Smarius if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) { 237209695Smarius sched_unpin(); 23891783Sjake return (NULL); 239209695Smarius } 24089051Sjake ita = &ipi_tlb_args; 241108187Sjake mtx_lock_spin(&ipi_mtx); 24292199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 24391783Sjake ita->ita_pmap = pm; 24489051Sjake ita->ita_start = start; 24589051Sjake ita->ita_end = end; 24691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 24792199Sjake return (&ita->ita_mask); 24889051Sjake} 24989051Sjake 25089051Sjakestatic __inline void 25189051Sjakeipi_wait(void *cookie) 25289051Sjake{ 253143190Salc volatile u_int *mask; 25489051Sjake 25592199Sjake if ((mask = cookie) != NULL) { 25692199Sjake atomic_clear_int(mask, PCPU_GET(cpumask)); 25792199Sjake while (*mask != 0) 25891617Sjake ; 259108187Sjake mtx_unlock_spin(&ipi_mtx); 260209695Smarius sched_unpin(); 26189051Sjake } 26289051Sjake} 26389051Sjake 264108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 26591783Sjake 266183142Smarius#endif /* !LOCORE */ 267183142Smarius 26889051Sjake#else 26989051Sjake 270183142Smarius#ifndef LOCORE 271183142Smarius 27289051Sjakestatic __inline void * 273209695Smariusipi_dcache_page_inval(void *func __unused, vm_paddr_t pa __unused) 27497001Sjake{ 275169796Smarius 27697001Sjake return (NULL); 27797001Sjake} 27897001Sjake 27997001Sjakestatic __inline void * 280209695Smariusipi_icache_page_inval(void *func __unused, vm_paddr_t pa __unused) 28197001Sjake{ 282169796Smarius 28397001Sjake return (NULL); 28497001Sjake} 28597001Sjake 28697001Sjakestatic __inline void * 287209695Smariusipi_tlb_context_demap(struct pmap *pm __unused) 28889051Sjake{ 289169796Smarius 29089051Sjake return (NULL); 29189051Sjake} 29289051Sjake 29389051Sjakestatic __inline void * 294209695Smariusipi_tlb_page_demap(struct pmap *pm __unused, vm_offset_t va __unused) 29589051Sjake{ 296169796Smarius 29789051Sjake return (NULL); 29889051Sjake} 29989051Sjake 30089051Sjakestatic __inline void * 301209695Smariusipi_tlb_range_demap(struct pmap *pm __unused, vm_offset_t start __unused, 302209695Smarius __unused vm_offset_t end) 30389051Sjake{ 304169796Smarius 30589051Sjake return (NULL); 30689051Sjake} 30789051Sjake 30889051Sjakestatic __inline void 30989051Sjakeipi_wait(void *cookie) 31089051Sjake{ 311169796Smarius 31289051Sjake} 31389051Sjake 314183142Smariusstatic __inline void 315183142Smariustl_ipi_cheetah_dcache_page_inval(void) 316183142Smarius{ 31789051Sjake 318183142Smarius} 319183142Smarius 320183142Smariusstatic __inline void 321183142Smariustl_ipi_spitfire_dcache_page_inval(void) 322183142Smarius{ 323183142Smarius 324183142Smarius} 325183142Smarius 326183142Smariusstatic __inline void 327183142Smariustl_ipi_spitfire_icache_page_inval(void) 328183142Smarius{ 329183142Smarius 330183142Smarius} 331183142Smarius 33289051Sjake#endif /* !LOCORE */ 33389051Sjake 334183142Smarius#endif /* SMP */ 335183142Smarius 33680708Sjake#endif /* !_MACHINE_SMP_H_ */ 337