smp.h revision 113238
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 113238 2003-04-08 06:35:09Z jake $ 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> 3991617Sjake#include <machine/tte.h> 4091157Sjake 4189051Sjake#define IDR_BUSY (1<<0) 4289051Sjake#define IDR_NACK (1<<1) 4389051Sjake 4489051Sjake#define IPI_AST PIL_AST 4589051Sjake#define IPI_RENDEZVOUS PIL_RENDEZVOUS 4689051Sjake#define IPI_STOP PIL_STOP 4789051Sjake 4889051Sjake#define IPI_RETRIES 100 4989051Sjake 5089051Sjakestruct cpu_start_args { 5191783Sjake u_int csa_count; 5289051Sjake u_int csa_mid; 5389051Sjake u_int csa_state; 5491783Sjake vm_offset_t csa_pcpu; 5591617Sjake u_long csa_tick; 5691617Sjake u_long csa_ver; 5791617Sjake struct tte csa_ttes[PCPU_PAGES]; 5889051Sjake}; 5989051Sjake 6097001Sjakestruct ipi_cache_args { 6197001Sjake u_int ica_mask; 62113238Sjake vm_paddr_t ica_pa; 6397001Sjake}; 6497001Sjake 6589051Sjakestruct ipi_tlb_args { 6692199Sjake u_int ita_mask; 6791783Sjake struct pmap *ita_pmap; 6889051Sjake u_long ita_start; 6989051Sjake u_long ita_end; 7089051Sjake}; 7189051Sjake#define ita_va ita_start 7289051Sjake 7389051Sjakestruct pcpu; 7489051Sjake 7589051Sjakevoid cpu_mp_bootstrap(struct pcpu *pc); 7692199Sjakevoid cpu_mp_shutdown(void); 7789051Sjake 7889051Sjakevoid cpu_ipi_selected(u_int cpus, u_long d0, u_long d1, u_long d2); 7989051Sjakevoid cpu_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2); 8089051Sjake 8189051Sjakevoid ipi_selected(u_int cpus, u_int ipi); 8289051Sjakevoid ipi_all(u_int ipi); 8389051Sjakevoid ipi_all_but_self(u_int ipi); 8489051Sjake 8591617Sjakevm_offset_t mp_tramp_alloc(void); 8691617Sjake 87108187Sjakeextern struct mtx ipi_mtx; 88108187Sjakeextern struct ipi_cache_args ipi_cache_args; 89108187Sjakeextern struct ipi_tlb_args ipi_tlb_args; 9089051Sjake 9191617Sjakeextern vm_offset_t mp_tramp; 9291617Sjakeextern char *mp_tramp_code; 9391617Sjakeextern u_long mp_tramp_code_len; 9491617Sjakeextern u_long mp_tramp_tlb_slots; 9591617Sjakeextern u_long mp_tramp_func; 9691617Sjake 9791617Sjakeextern void mp_startup(void); 9891617Sjake 99112399Sjakeextern char tl_ipi_cheetah_dcache_page_inval[]; 100112399Sjakeextern char tl_ipi_spitfire_dcache_page_inval[]; 101112399Sjakeextern char tl_ipi_spitfire_icache_page_inval[]; 102112399Sjake 10389051Sjakeextern char tl_ipi_level[]; 10489051Sjakeextern char tl_ipi_tlb_context_demap[]; 10589051Sjakeextern char tl_ipi_tlb_page_demap[]; 10689051Sjakeextern char tl_ipi_tlb_range_demap[]; 10789051Sjake 10889051Sjake#ifdef SMP 10989051Sjake 110108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) 111108187Sjake 11297001Sjakestatic __inline void * 113113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 11497001Sjake{ 11597001Sjake struct ipi_cache_args *ica; 11697001Sjake 11797001Sjake if (smp_cpus == 1) 11897001Sjake return (NULL); 11997001Sjake ica = &ipi_cache_args; 120108187Sjake mtx_lock_spin(&ipi_mtx); 12197001Sjake ica->ica_mask = all_cpus; 12297001Sjake ica->ica_pa = pa; 123112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 12497001Sjake return (&ica->ica_mask); 12597001Sjake} 12697001Sjake 12797001Sjakestatic __inline void * 128113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 12997001Sjake{ 13097001Sjake struct ipi_cache_args *ica; 13197001Sjake 13297001Sjake if (smp_cpus == 1) 13397001Sjake return (NULL); 13497001Sjake ica = &ipi_cache_args; 135108187Sjake mtx_lock_spin(&ipi_mtx); 13697001Sjake ica->ica_mask = all_cpus; 13797001Sjake ica->ica_pa = pa; 138112399Sjake cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica); 13997001Sjake return (&ica->ica_mask); 14097001Sjake} 14197001Sjake 14289051Sjakestatic __inline void * 14391783Sjakeipi_tlb_context_demap(struct pmap *pm) 14489051Sjake{ 14589051Sjake struct ipi_tlb_args *ita; 14691783Sjake u_int cpus; 14789051Sjake 14891783Sjake if (smp_cpus == 1) 14989051Sjake return (NULL); 15091783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 15191783Sjake return (NULL); 15289051Sjake ita = &ipi_tlb_args; 153108187Sjake mtx_lock_spin(&ipi_mtx); 15492199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 15591783Sjake ita->ita_pmap = pm; 15691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap, 15791783Sjake (u_long)ita); 15892199Sjake return (&ita->ita_mask); 15989051Sjake} 16089051Sjake 16189051Sjakestatic __inline void * 162100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 16389051Sjake{ 16489051Sjake struct ipi_tlb_args *ita; 16591783Sjake u_int cpus; 16689051Sjake 16791783Sjake if (smp_cpus == 1) 16889051Sjake return (NULL); 16991783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 17091783Sjake return (NULL); 17189051Sjake ita = &ipi_tlb_args; 172108187Sjake mtx_lock_spin(&ipi_mtx); 17392199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 17491783Sjake ita->ita_pmap = pm; 17589051Sjake ita->ita_va = va; 17691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita); 17792199Sjake return (&ita->ita_mask); 17889051Sjake} 17989051Sjake 18089051Sjakestatic __inline void * 18191783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 18289051Sjake{ 18389051Sjake struct ipi_tlb_args *ita; 18491783Sjake u_int cpus; 18589051Sjake 18691783Sjake if (smp_cpus == 1) 18789051Sjake return (NULL); 18891783Sjake if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0) 18991783Sjake return (NULL); 19089051Sjake ita = &ipi_tlb_args; 191108187Sjake mtx_lock_spin(&ipi_mtx); 19292199Sjake ita->ita_mask = cpus | PCPU_GET(cpumask); 19391783Sjake ita->ita_pmap = pm; 19489051Sjake ita->ita_start = start; 19589051Sjake ita->ita_end = end; 19691783Sjake cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita); 19792199Sjake return (&ita->ita_mask); 19889051Sjake} 19989051Sjake 20089051Sjakestatic __inline void 20189051Sjakeipi_wait(void *cookie) 20289051Sjake{ 20392199Sjake u_int *volatile mask; 20489051Sjake 20592199Sjake if ((mask = cookie) != NULL) { 20692199Sjake atomic_clear_int(mask, PCPU_GET(cpumask)); 20792199Sjake while (*mask != 0) 20891617Sjake ; 209108187Sjake mtx_unlock_spin(&ipi_mtx); 21089051Sjake } 21189051Sjake} 21289051Sjake 213108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ 21491783Sjake 21589051Sjake#else 21689051Sjake 21789051Sjakestatic __inline void * 218113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa) 21997001Sjake{ 22097001Sjake return (NULL); 22197001Sjake} 22297001Sjake 22397001Sjakestatic __inline void * 224113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa) 22597001Sjake{ 22697001Sjake return (NULL); 22797001Sjake} 22897001Sjake 22997001Sjakestatic __inline void * 23091783Sjakeipi_tlb_context_demap(struct pmap *pm) 23189051Sjake{ 23289051Sjake return (NULL); 23389051Sjake} 23489051Sjake 23589051Sjakestatic __inline void * 236100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va) 23789051Sjake{ 23889051Sjake return (NULL); 23989051Sjake} 24089051Sjake 24189051Sjakestatic __inline void * 24291783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end) 24389051Sjake{ 24489051Sjake return (NULL); 24589051Sjake} 24689051Sjake 24789051Sjakestatic __inline void 24889051Sjakeipi_wait(void *cookie) 24989051Sjake{ 25089051Sjake} 25189051Sjake 25289051Sjake#endif /* SMP */ 25389051Sjake 25489051Sjake#endif /* !LOCORE */ 25589051Sjake 25680708Sjake#endif /* !_MACHINE_SMP_H_ */ 257