smp.h revision 169730
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 169730 2007-05-19 05:01:43Z kan $
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
4289051Sjake#define	IDR_BUSY	(1<<0)
4389051Sjake#define	IDR_NACK	(1<<1)
4489051Sjake
4589051Sjake#define	IPI_AST		PIL_AST
4689051Sjake#define	IPI_RENDEZVOUS	PIL_RENDEZVOUS
4789051Sjake#define	IPI_STOP	PIL_STOP
4889051Sjake
49135943Skensmith#define	IPI_RETRIES	5000
5089051Sjake
5189051Sjakestruct cpu_start_args {
5291783Sjake	u_int	csa_count;
5389051Sjake	u_int	csa_mid;
5489051Sjake	u_int	csa_state;
5591783Sjake	vm_offset_t csa_pcpu;
5691617Sjake	u_long	csa_tick;
5791617Sjake	u_long	csa_ver;
5891617Sjake	struct	tte csa_ttes[PCPU_PAGES];
5989051Sjake};
6089051Sjake
6197001Sjakestruct ipi_cache_args {
6297001Sjake	u_int	ica_mask;
63113238Sjake	vm_paddr_t ica_pa;
6497001Sjake};
6597001Sjake
6689051Sjakestruct ipi_tlb_args {
6792199Sjake	u_int	ita_mask;
6891783Sjake	struct	pmap *ita_pmap;
6989051Sjake	u_long	ita_start;
7089051Sjake	u_long	ita_end;
7189051Sjake};
7289051Sjake#define	ita_va	ita_start
7389051Sjake
7489051Sjakestruct pcpu;
7589051Sjake
76152022Sjhbextern struct pcb stoppcbs[];
77152022Sjhb
7889051Sjakevoid	cpu_mp_bootstrap(struct pcpu *pc);
7992199Sjakevoid	cpu_mp_shutdown(void);
8089051Sjake
8189051Sjakevoid	cpu_ipi_selected(u_int cpus, u_long d0, u_long d1, u_long d2);
8289051Sjakevoid	cpu_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2);
8389051Sjake
8489051Sjakevoid	ipi_selected(u_int cpus, u_int ipi);
8589051Sjakevoid	ipi_all(u_int ipi);
8689051Sjakevoid	ipi_all_but_self(u_int ipi);
8789051Sjake
8891617Sjakevm_offset_t mp_tramp_alloc(void);
8991617Sjake
90108187Sjakeextern	struct mtx ipi_mtx;
91108187Sjakeextern	struct ipi_cache_args ipi_cache_args;
92108187Sjakeextern	struct ipi_tlb_args ipi_tlb_args;
9389051Sjake
9491617Sjakeextern	vm_offset_t mp_tramp;
9591617Sjakeextern	char *mp_tramp_code;
9691617Sjakeextern	u_long mp_tramp_code_len;
9791617Sjakeextern	u_long mp_tramp_tlb_slots;
9891617Sjakeextern	u_long mp_tramp_func;
9991617Sjake
10091617Sjakeextern	void mp_startup(void);
10191617Sjake
102112399Sjakeextern	char tl_ipi_cheetah_dcache_page_inval[];
103112399Sjakeextern	char tl_ipi_spitfire_dcache_page_inval[];
104112399Sjakeextern	char tl_ipi_spitfire_icache_page_inval[];
105112399Sjake
10689051Sjakeextern	char tl_ipi_level[];
10789051Sjakeextern	char tl_ipi_tlb_context_demap[];
10889051Sjakeextern	char tl_ipi_tlb_page_demap[];
10989051Sjakeextern	char tl_ipi_tlb_range_demap[];
11089051Sjake
11189051Sjake#ifdef SMP
11289051Sjake
113108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
114108187Sjake
11597001Sjakestatic __inline void *
116113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
11797001Sjake{
11897001Sjake	struct ipi_cache_args *ica;
11997001Sjake
12097001Sjake	if (smp_cpus == 1)
12197001Sjake		return (NULL);
12297001Sjake	ica = &ipi_cache_args;
123108187Sjake	mtx_lock_spin(&ipi_mtx);
12497001Sjake	ica->ica_mask = all_cpus;
12597001Sjake	ica->ica_pa = pa;
126112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
12797001Sjake	return (&ica->ica_mask);
12897001Sjake}
12997001Sjake
13097001Sjakestatic __inline void *
131113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
13297001Sjake{
13397001Sjake	struct ipi_cache_args *ica;
13497001Sjake
13597001Sjake	if (smp_cpus == 1)
13697001Sjake		return (NULL);
13797001Sjake	ica = &ipi_cache_args;
138108187Sjake	mtx_lock_spin(&ipi_mtx);
13997001Sjake	ica->ica_mask = all_cpus;
14097001Sjake	ica->ica_pa = pa;
141112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
14297001Sjake	return (&ica->ica_mask);
14397001Sjake}
14497001Sjake
14589051Sjakestatic __inline void *
14691783Sjakeipi_tlb_context_demap(struct pmap *pm)
14789051Sjake{
14889051Sjake	struct ipi_tlb_args *ita;
14991783Sjake	u_int cpus;
15089051Sjake
15191783Sjake	if (smp_cpus == 1)
15289051Sjake		return (NULL);
15391783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
15491783Sjake		return (NULL);
15589051Sjake	ita = &ipi_tlb_args;
156108187Sjake	mtx_lock_spin(&ipi_mtx);
15792199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
15891783Sjake	ita->ita_pmap = pm;
15991783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
16091783Sjake	    (u_long)ita);
16192199Sjake	return (&ita->ita_mask);
16289051Sjake}
16389051Sjake
16489051Sjakestatic __inline void *
165100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
16689051Sjake{
16789051Sjake	struct ipi_tlb_args *ita;
16891783Sjake	u_int cpus;
16989051Sjake
17091783Sjake	if (smp_cpus == 1)
17189051Sjake		return (NULL);
17291783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
17391783Sjake		return (NULL);
17489051Sjake	ita = &ipi_tlb_args;
175108187Sjake	mtx_lock_spin(&ipi_mtx);
17692199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
17791783Sjake	ita->ita_pmap = pm;
17889051Sjake	ita->ita_va = va;
17991783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
18092199Sjake	return (&ita->ita_mask);
18189051Sjake}
18289051Sjake
18389051Sjakestatic __inline void *
18491783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
18589051Sjake{
18689051Sjake	struct ipi_tlb_args *ita;
18791783Sjake	u_int cpus;
18889051Sjake
18991783Sjake	if (smp_cpus == 1)
19089051Sjake		return (NULL);
19191783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
19291783Sjake		return (NULL);
19389051Sjake	ita = &ipi_tlb_args;
194108187Sjake	mtx_lock_spin(&ipi_mtx);
19592199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
19691783Sjake	ita->ita_pmap = pm;
19789051Sjake	ita->ita_start = start;
19889051Sjake	ita->ita_end = end;
19991783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita);
20092199Sjake	return (&ita->ita_mask);
20189051Sjake}
20289051Sjake
20389051Sjakestatic __inline void
20489051Sjakeipi_wait(void *cookie)
20589051Sjake{
206143190Salc	volatile u_int *mask;
20789051Sjake
20892199Sjake	if ((mask = cookie) != NULL) {
20992199Sjake		atomic_clear_int(mask, PCPU_GET(cpumask));
21092199Sjake		while (*mask != 0)
21191617Sjake			;
212108187Sjake		mtx_unlock_spin(&ipi_mtx);
21389051Sjake	}
21489051Sjake}
21589051Sjake
216108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
21791783Sjake
21889051Sjake#else
21989051Sjake
22089051Sjakestatic __inline void *
221113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
22297001Sjake{
22397001Sjake	return (NULL);
22497001Sjake}
22597001Sjake
22697001Sjakestatic __inline void *
227113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
22897001Sjake{
22997001Sjake	return (NULL);
23097001Sjake}
23197001Sjake
23297001Sjakestatic __inline void *
23391783Sjakeipi_tlb_context_demap(struct pmap *pm)
23489051Sjake{
23589051Sjake	return (NULL);
23689051Sjake}
23789051Sjake
23889051Sjakestatic __inline void *
239100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
24089051Sjake{
24189051Sjake	return (NULL);
24289051Sjake}
24389051Sjake
24489051Sjakestatic __inline void *
24591783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
24689051Sjake{
24789051Sjake	return (NULL);
24889051Sjake}
24989051Sjake
25089051Sjakestatic __inline void
25189051Sjakeipi_wait(void *cookie)
25289051Sjake{
25389051Sjake}
25489051Sjake
25589051Sjake#endif /* SMP */
25689051Sjake
25789051Sjake#endif /* !LOCORE */
25889051Sjake
25980708Sjake#endif /* !_MACHINE_SMP_H_ */
260