smp.h revision 211050
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 211050 2010-08-08 00:09:22Z marius $ 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; 101211050Smariustypedef void cpu_ipi_single_t(u_int, u_long, u_long, u_long); 102211050Smariusextern cpu_ipi_single_t *cpu_ipi_single; 10389051Sjake 104204152Smariusvoid mp_init(u_int cpu_impl); 10591617Sjake 106108187Sjakeextern struct mtx ipi_mtx; 107108187Sjakeextern struct ipi_cache_args ipi_cache_args; 108108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 10989051Sjake 11091617Sjakeextern char *mp_tramp_code; 11191617Sjakeextern u_long mp_tramp_code_len; 11291617Sjakeextern u_long mp_tramp_tlb_slots; 11391617Sjakeextern u_long mp_tramp_func; 11491617Sjake 11591617Sjakeextern void mp_startup(void); 11691617Sjake 117112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 118112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 119112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 120112399Sjake 12189051Sjakeextern char tl_ipi_level[]; 12289051Sjakeextern char tl_ipi_tlb_context_demap[]; 12389051Sjakeextern char tl_ipi_tlb_page_demap[]; 12489051Sjakeextern char tl_ipi_tlb_range_demap[]; 12589051Sjake 126183142Smariusstatic __inline void 127183142Smariusipi_all_but_self(u_int ipi) 128183142Smarius{ 12989051Sjake 130183142Smarius cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi); 131183142Smarius} 132183142Smarius 133183142Smariusstatic __inline void 134183142Smariusipi_selected(u_int cpus, u_int ipi) 135183142Smarius{ 136183142Smarius 137183142Smarius cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); 138183142Smarius} 139183142Smarius 140210939Sjhbstatic __inline void 141210939Sjhbipi_cpu(int cpu, u_int ipi) 142210939Sjhb{ 143210939Sjhb 144211050Smarius cpu_ipi_single(cpu, 0, (u_long)tl_ipi_level, ipi); 145210939Sjhb} 146210939Sjhb 147108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 148108187Sjake 14997001Sjakestatic __inline void * 150113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 15197001Sjake{ 15297001Sjake struct ipi_cache_args *ica; 15397001Sjake 15497001Sjake if (smp_cpus == 1) 15597001Sjake return (NULL); 156209695Smarius sched_pin(); 15797001Sjake ica = &ipi_cache_args; 158108187Sjake mtx_lock_spin(&ipi_mtx); 15997001Sjake ica->ica_mask = all_cpus; 16097001Sjake ica->ica_pa = pa; 161112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 16297001Sjake return (&ica->ica_mask); 16397001Sjake} 16497001Sjake 16597001Sjakestatic __inline void * 166113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 16797001Sjake{ 16897001Sjake struct ipi_cache_args *ica; 16997001Sjake 17097001Sjake if (smp_cpus == 1) 17197001Sjake return (NULL); 172209695Smarius sched_pin(); 17397001Sjake ica = &ipi_cache_args; 174108187Sjake mtx_lock_spin(&ipi_mtx); 17597001Sjake ica->ica_mask = all_cpus; 17697001Sjake ica->ica_pa = pa; 177112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 17897001Sjake return (&ica->ica_mask); 17997001Sjake} 18097001Sjake 18189051Sjakestatic __inline void * 18291783Sjakeipi_tlb_context_demap(struct pmap *pm) 18389051Sjake{ 18489051Sjake struct ipi_tlb_args *ita; 18591783Sjake u_int cpus; 18689051Sjake 18791783Sjake if (smp_cpus == 1) 18889051Sjake return (NULL); 189209695Smarius sched_pin(); 190209695Smarius if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) { 191209695Smarius sched_unpin(); 19291783Sjake return (NULL); 193209695Smarius } 19489051Sjake ita = &ipi_tlb_args; 195108187Sjake mtx_lock_spin(&ipi_mtx); 19692199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 19791783Sjake ita->ita_pmap = pm; 19891783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 19991783Sjake (u_long)ita); 20092199Sjake return (&ita->ita_mask); 20189051Sjake} 20289051Sjake 20389051Sjakestatic __inline void * 204100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 20589051Sjake{ 20689051Sjake struct ipi_tlb_args *ita; 20791783Sjake u_int cpus; 20889051Sjake 20991783Sjake if (smp_cpus == 1) 21089051Sjake return (NULL); 211209695Smarius sched_pin(); 212209695Smarius if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) { 213209695Smarius sched_unpin(); 21491783Sjake return (NULL); 215209695Smarius } 21689051Sjake ita = &ipi_tlb_args; 217108187Sjake mtx_lock_spin(&ipi_mtx); 21892199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 21991783Sjake ita->ita_pmap = pm; 22089051Sjake ita->ita_va = va; 22191783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 22292199Sjake return (&ita->ita_mask); 22389051Sjake} 22489051Sjake 22589051Sjakestatic __inline void * 22691783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 22789051Sjake{ 22889051Sjake struct ipi_tlb_args *ita; 22991783Sjake u_int cpus; 23089051Sjake 23191783Sjake if (smp_cpus == 1) 23289051Sjake return (NULL); 233209695Smarius sched_pin(); 234209695Smarius if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) { 235209695Smarius sched_unpin(); 23691783Sjake return (NULL); 237209695Smarius } 23889051Sjake ita = &ipi_tlb_args; 239108187Sjake mtx_lock_spin(&ipi_mtx); 24092199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 24191783Sjake ita->ita_pmap = pm; 24289051Sjake ita->ita_start = start; 24389051Sjake ita->ita_end = end; 244211050Smarius cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, 245211050Smarius (u_long)ita); 24692199Sjake return (&ita->ita_mask); 24789051Sjake} 24889051Sjake 24989051Sjakestatic __inline void 25089051Sjakeipi_wait(void *cookie) 25189051Sjake{ 252143190Salc volatile u_int *mask; 25389051Sjake 25492199Sjake if ((mask = cookie) != NULL) { 25592199Sjake atomic_clear_int(mask, PCPU_GET(cpumask)); 25692199Sjake while (*mask != 0) 25791617Sjake ; 258108187Sjake mtx_unlock_spin(&ipi_mtx); 259209695Smarius sched_unpin(); 26089051Sjake } 26189051Sjake} 26289051Sjake 263108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 26491783Sjake 265183142Smarius#endif /* !LOCORE */ 266183142Smarius 26789051Sjake#else 26889051Sjake 269183142Smarius#ifndef LOCORE 270183142Smarius 27189051Sjakestatic __inline void * 272209695Smariusipi_dcache_page_inval(void *func __unused, vm_paddr_t pa __unused) 27397001Sjake{ 274169796Smarius 27597001Sjake return (NULL); 27697001Sjake} 27797001Sjake 27897001Sjakestatic __inline void * 279209695Smariusipi_icache_page_inval(void *func __unused, vm_paddr_t pa __unused) 28097001Sjake{ 281169796Smarius 28297001Sjake return (NULL); 28397001Sjake} 28497001Sjake 28597001Sjakestatic __inline void * 286209695Smariusipi_tlb_context_demap(struct pmap *pm __unused) 28789051Sjake{ 288169796Smarius 28989051Sjake return (NULL); 29089051Sjake} 29189051Sjake 29289051Sjakestatic __inline void * 293209695Smariusipi_tlb_page_demap(struct pmap *pm __unused, vm_offset_t va __unused) 29489051Sjake{ 295169796Smarius 29689051Sjake return (NULL); 29789051Sjake} 29889051Sjake 29989051Sjakestatic __inline void * 300209695Smariusipi_tlb_range_demap(struct pmap *pm __unused, vm_offset_t start __unused, 301209695Smarius __unused vm_offset_t end) 30289051Sjake{ 303169796Smarius 30489051Sjake return (NULL); 30589051Sjake} 30689051Sjake 30789051Sjakestatic __inline void 30889051Sjakeipi_wait(void *cookie) 30989051Sjake{ 310169796Smarius 31189051Sjake} 31289051Sjake 313183142Smariusstatic __inline void 314183142Smariustl_ipi_cheetah_dcache_page_inval(void) 315183142Smarius{ 31689051Sjake 317183142Smarius} 318183142Smarius 319183142Smariusstatic __inline void 320183142Smariustl_ipi_spitfire_dcache_page_inval(void) 321183142Smarius{ 322183142Smarius 323183142Smarius} 324183142Smarius 325183142Smariusstatic __inline void 326183142Smariustl_ipi_spitfire_icache_page_inval(void) 327183142Smarius{ 328183142Smarius 329183142Smarius} 330183142Smarius 33189051Sjake#endif /* !LOCORE */ 33289051Sjake 333183142Smarius#endif /* SMP */ 334183142Smarius 33580708Sjake#endif /* !_MACHINE_SMP_H_ */ 336