smp.h revision 178048
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 178048 2008-04-09 21:14:01Z marius $ 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 42170846Smarius#define IDR_BUSY 0x0000000000000001ULL 43170846Smarius#define IDR_NACK 0x0000000000000002ULL 44170846Smarius#define IDR_CHEETAH_ALL_BUSY 0x5555555555555555ULL 45170846Smarius#define IDR_CHEETAH_ALL_NACK (~IDR_CHEETAH_ALL_BUSY) 46170846Smarius#define IDR_CHEETAH_MAX_BN_PAIRS 32 47170846Smarius#define IDR_JALAPENO_MAX_BN_PAIRS 4 4889051Sjake 49169796Smarius#define IDC_ITID_SHIFT 14 50170846Smarius#define IDC_BN_SHIFT 24 51169796Smarius 5289051Sjake#define IPI_AST PIL_AST 5389051Sjake#define IPI_RENDEZVOUS PIL_RENDEZVOUS 54178048Smarius#define IPI_PREEMPT PIL_PREEMPT 5589051Sjake#define IPI_STOP PIL_STOP 5689051Sjake 57135943Skensmith#define IPI_RETRIES 5000 5889051Sjake 5989051Sjakestruct cpu_start_args { 6091783Sjake u_int csa_count; 6189051Sjake u_int csa_mid; 6289051Sjake u_int csa_state; 6391783Sjake vm_offset_t csa_pcpu; 6491617Sjake u_long csa_tick; 6591617Sjake u_long csa_ver; 6691617Sjake struct tte csa_ttes[PCPU_PAGES]; 6789051Sjake}; 6889051Sjake 6997001Sjakestruct ipi_cache_args { 7097001Sjake u_int ica_mask; 71113238Sjake vm_paddr_t ica_pa; 7297001Sjake}; 7397001Sjake 7489051Sjakestruct ipi_tlb_args { 7592199Sjake u_int ita_mask; 7691783Sjake struct pmap *ita_pmap; 7789051Sjake u_long ita_start; 7889051Sjake u_long ita_end; 7989051Sjake}; 8089051Sjake#define ita_va ita_start 8189051Sjake 8289051Sjakestruct pcpu; 8389051Sjake 84152022Sjhbextern struct pcb stoppcbs[]; 85152022Sjhb 8689051Sjakevoid cpu_mp_bootstrap(struct pcpu *pc); 8792199Sjakevoid cpu_mp_shutdown(void); 8889051Sjake 89170846Smariustypedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long); 90170846Smariusextern cpu_ipi_selected_t *cpu_ipi_selected; 9189051Sjake 9289051Sjakevoid ipi_selected(u_int cpus, u_int ipi); 9389051Sjakevoid ipi_all(u_int ipi); 9489051Sjakevoid ipi_all_but_self(u_int ipi); 9589051Sjake 96170846Smariusvoid mp_init(void); 9791617Sjake 98108187Sjakeextern struct mtx ipi_mtx; 99108187Sjakeextern struct ipi_cache_args ipi_cache_args; 100108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 10189051Sjake 10291617Sjakeextern char *mp_tramp_code; 10391617Sjakeextern u_long mp_tramp_code_len; 10491617Sjakeextern u_long mp_tramp_tlb_slots; 10591617Sjakeextern u_long mp_tramp_func; 10691617Sjake 10791617Sjakeextern void mp_startup(void); 10891617Sjake 109112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 110112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 111112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 112112399Sjake 11389051Sjakeextern char tl_ipi_level[]; 11489051Sjakeextern char tl_ipi_tlb_context_demap[]; 11589051Sjakeextern char tl_ipi_tlb_page_demap[]; 11689051Sjakeextern char tl_ipi_tlb_range_demap[]; 11789051Sjake 11889051Sjake#ifdef SMP 11989051Sjake 120108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 121108187Sjake 12297001Sjakestatic __inline void * 123113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 12497001Sjake{ 12597001Sjake struct ipi_cache_args *ica; 12697001Sjake 12797001Sjake if (smp_cpus == 1) 12897001Sjake return (NULL); 12997001Sjake ica = &ipi_cache_args; 130108187Sjake mtx_lock_spin(&ipi_mtx); 13197001Sjake ica->ica_mask = all_cpus; 13297001Sjake ica->ica_pa = pa; 133112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 13497001Sjake return (&ica->ica_mask); 13597001Sjake} 13697001Sjake 13797001Sjakestatic __inline void * 138113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 13997001Sjake{ 14097001Sjake struct ipi_cache_args *ica; 14197001Sjake 14297001Sjake if (smp_cpus == 1) 14397001Sjake return (NULL); 14497001Sjake ica = &ipi_cache_args; 145108187Sjake mtx_lock_spin(&ipi_mtx); 14697001Sjake ica->ica_mask = all_cpus; 14797001Sjake ica->ica_pa = pa; 148112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 14997001Sjake return (&ica->ica_mask); 15097001Sjake} 15197001Sjake 15289051Sjakestatic __inline void * 15391783Sjakeipi_tlb_context_demap(struct pmap *pm) 15489051Sjake{ 15589051Sjake struct ipi_tlb_args *ita; 15691783Sjake u_int cpus; 15789051Sjake 15891783Sjake if (smp_cpus == 1) 15989051Sjake return (NULL); 16091783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 16191783Sjake return (NULL); 16289051Sjake ita = &ipi_tlb_args; 163108187Sjake mtx_lock_spin(&ipi_mtx); 16492199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 16591783Sjake ita->ita_pmap = pm; 16691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 16791783Sjake (u_long)ita); 16892199Sjake return (&ita->ita_mask); 16989051Sjake} 17089051Sjake 17189051Sjakestatic __inline void * 172100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 17389051Sjake{ 17489051Sjake struct ipi_tlb_args *ita; 17591783Sjake u_int cpus; 17689051Sjake 17791783Sjake if (smp_cpus == 1) 17889051Sjake return (NULL); 17991783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 18091783Sjake return (NULL); 18189051Sjake ita = &ipi_tlb_args; 182108187Sjake mtx_lock_spin(&ipi_mtx); 18392199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 18491783Sjake ita->ita_pmap = pm; 18589051Sjake ita->ita_va = va; 18691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 18792199Sjake return (&ita->ita_mask); 18889051Sjake} 18989051Sjake 19089051Sjakestatic __inline void * 19191783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 19289051Sjake{ 19389051Sjake struct ipi_tlb_args *ita; 19491783Sjake u_int cpus; 19589051Sjake 19691783Sjake if (smp_cpus == 1) 19789051Sjake return (NULL); 19891783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 19991783Sjake return (NULL); 20089051Sjake ita = &ipi_tlb_args; 201108187Sjake mtx_lock_spin(&ipi_mtx); 20292199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 20391783Sjake ita->ita_pmap = pm; 20489051Sjake ita->ita_start = start; 20589051Sjake ita->ita_end = end; 20691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 20792199Sjake return (&ita->ita_mask); 20889051Sjake} 20989051Sjake 21089051Sjakestatic __inline void 21189051Sjakeipi_wait(void *cookie) 21289051Sjake{ 213143190Salc volatile u_int *mask; 21489051Sjake 21592199Sjake if ((mask = cookie) != NULL) { 21692199Sjake atomic_clear_int(mask, PCPU_GET(cpumask)); 21792199Sjake while (*mask != 0) 21891617Sjake ; 219108187Sjake mtx_unlock_spin(&ipi_mtx); 22089051Sjake } 22189051Sjake} 22289051Sjake 223108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 22491783Sjake 22589051Sjake#else 22689051Sjake 22789051Sjakestatic __inline void * 228113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 22997001Sjake{ 230169796Smarius 23197001Sjake return (NULL); 23297001Sjake} 23397001Sjake 23497001Sjakestatic __inline void * 235113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 23697001Sjake{ 237169796Smarius 23897001Sjake return (NULL); 23997001Sjake} 24097001Sjake 24197001Sjakestatic __inline void * 24291783Sjakeipi_tlb_context_demap(struct pmap *pm) 24389051Sjake{ 244169796Smarius 24589051Sjake return (NULL); 24689051Sjake} 24789051Sjake 24889051Sjakestatic __inline void * 249100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 25089051Sjake{ 251169796Smarius 25289051Sjake return (NULL); 25389051Sjake} 25489051Sjake 25589051Sjakestatic __inline void * 25691783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 25789051Sjake{ 258169796Smarius 25989051Sjake return (NULL); 26089051Sjake} 26189051Sjake 26289051Sjakestatic __inline void 26389051Sjakeipi_wait(void *cookie) 26489051Sjake{ 265169796Smarius 26689051Sjake} 26789051Sjake 26889051Sjake#endif /* SMP */ 26989051Sjake 27089051Sjake#endif /* !LOCORE */ 27189051Sjake 27280708Sjake#endif /* !_MACHINE_SMP_H_ */ 273