smp.h revision 182730
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 182730 2008-09-03 17:39:19Z marius $
2780708Sjake */
2880708Sjake
2980708Sjake#ifndef	_MACHINE_SMP_H_
3080708Sjake#define	_MACHINE_SMP_H_
3180708Sjake
32182730Smarius#define	CPU_TICKSYNC		1
33182730Smarius#define	CPU_STICKSYNC		2
34182730Smarius#define	CPU_INIT		3
35182730Smarius#define	CPU_BOOTSTRAP		4
3689051Sjake
3789051Sjake#ifndef	LOCORE
3889051Sjake
3991157Sjake#include <machine/intr_machdep.h>
40169730Skan#include <machine/pcb.h>
4191617Sjake#include <machine/tte.h>
4291157Sjake
43170846Smarius#define	IDR_BUSY			0x0000000000000001ULL
44170846Smarius#define	IDR_NACK			0x0000000000000002ULL
45170846Smarius#define	IDR_CHEETAH_ALL_BUSY		0x5555555555555555ULL
46170846Smarius#define	IDR_CHEETAH_ALL_NACK		(~IDR_CHEETAH_ALL_BUSY)
47170846Smarius#define	IDR_CHEETAH_MAX_BN_PAIRS	32
48170846Smarius#define	IDR_JALAPENO_MAX_BN_PAIRS	4
4989051Sjake
50169796Smarius#define	IDC_ITID_SHIFT			14
51170846Smarius#define	IDC_BN_SHIFT			24
52169796Smarius
5389051Sjake#define	IPI_AST		PIL_AST
5489051Sjake#define	IPI_RENDEZVOUS	PIL_RENDEZVOUS
55178048Smarius#define	IPI_PREEMPT	PIL_PREEMPT
5689051Sjake#define	IPI_STOP	PIL_STOP
5789051Sjake
58135943Skensmith#define	IPI_RETRIES	5000
5989051Sjake
6089051Sjakestruct cpu_start_args {
6191783Sjake	u_int	csa_count;
6289051Sjake	u_int	csa_mid;
6389051Sjake	u_int	csa_state;
6491783Sjake	vm_offset_t csa_pcpu;
6591617Sjake	u_long	csa_tick;
66182730Smarius	u_long	csa_stick;
6791617Sjake	u_long	csa_ver;
6891617Sjake	struct	tte csa_ttes[PCPU_PAGES];
6989051Sjake};
7089051Sjake
7197001Sjakestruct ipi_cache_args {
7297001Sjake	u_int	ica_mask;
73113238Sjake	vm_paddr_t ica_pa;
7497001Sjake};
7597001Sjake
7689051Sjakestruct ipi_tlb_args {
7792199Sjake	u_int	ita_mask;
7891783Sjake	struct	pmap *ita_pmap;
7989051Sjake	u_long	ita_start;
8089051Sjake	u_long	ita_end;
8189051Sjake};
8289051Sjake#define	ita_va	ita_start
8389051Sjake
8489051Sjakestruct pcpu;
8589051Sjake
86152022Sjhbextern struct pcb stoppcbs[];
87152022Sjhb
8889051Sjakevoid	cpu_mp_bootstrap(struct pcpu *pc);
8992199Sjakevoid	cpu_mp_shutdown(void);
9089051Sjake
91170846Smariustypedef	void cpu_ipi_selected_t(u_int, u_long, u_long, u_long);
92170846Smariusextern	cpu_ipi_selected_t *cpu_ipi_selected;
9389051Sjake
9489051Sjakevoid	ipi_selected(u_int cpus, u_int ipi);
9589051Sjakevoid	ipi_all(u_int ipi);
9689051Sjakevoid	ipi_all_but_self(u_int ipi);
9789051Sjake
98170846Smariusvoid	mp_init(void);
9991617Sjake
100108187Sjakeextern	struct mtx ipi_mtx;
101108187Sjakeextern	struct ipi_cache_args ipi_cache_args;
102108187Sjakeextern	struct ipi_tlb_args ipi_tlb_args;
10389051Sjake
10491617Sjakeextern	char *mp_tramp_code;
10591617Sjakeextern	u_long mp_tramp_code_len;
10691617Sjakeextern	u_long mp_tramp_tlb_slots;
10791617Sjakeextern	u_long mp_tramp_func;
10891617Sjake
10991617Sjakeextern	void mp_startup(void);
11091617Sjake
111112399Sjakeextern	char tl_ipi_cheetah_dcache_page_inval[];
112112399Sjakeextern	char tl_ipi_spitfire_dcache_page_inval[];
113112399Sjakeextern	char tl_ipi_spitfire_icache_page_inval[];
114112399Sjake
11589051Sjakeextern	char tl_ipi_level[];
11689051Sjakeextern	char tl_ipi_tlb_context_demap[];
11789051Sjakeextern	char tl_ipi_tlb_page_demap[];
11889051Sjakeextern	char tl_ipi_tlb_range_demap[];
11989051Sjake
12089051Sjake#ifdef SMP
12189051Sjake
122108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
123108187Sjake
12497001Sjakestatic __inline void *
125113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
12697001Sjake{
12797001Sjake	struct ipi_cache_args *ica;
12897001Sjake
12997001Sjake	if (smp_cpus == 1)
13097001Sjake		return (NULL);
13197001Sjake	ica = &ipi_cache_args;
132108187Sjake	mtx_lock_spin(&ipi_mtx);
13397001Sjake	ica->ica_mask = all_cpus;
13497001Sjake	ica->ica_pa = pa;
135112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
13697001Sjake	return (&ica->ica_mask);
13797001Sjake}
13897001Sjake
13997001Sjakestatic __inline void *
140113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
14197001Sjake{
14297001Sjake	struct ipi_cache_args *ica;
14397001Sjake
14497001Sjake	if (smp_cpus == 1)
14597001Sjake		return (NULL);
14697001Sjake	ica = &ipi_cache_args;
147108187Sjake	mtx_lock_spin(&ipi_mtx);
14897001Sjake	ica->ica_mask = all_cpus;
14997001Sjake	ica->ica_pa = pa;
150112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
15197001Sjake	return (&ica->ica_mask);
15297001Sjake}
15397001Sjake
15489051Sjakestatic __inline void *
15591783Sjakeipi_tlb_context_demap(struct pmap *pm)
15689051Sjake{
15789051Sjake	struct ipi_tlb_args *ita;
15891783Sjake	u_int cpus;
15989051Sjake
16091783Sjake	if (smp_cpus == 1)
16189051Sjake		return (NULL);
16291783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
16391783Sjake		return (NULL);
16489051Sjake	ita = &ipi_tlb_args;
165108187Sjake	mtx_lock_spin(&ipi_mtx);
16692199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
16791783Sjake	ita->ita_pmap = pm;
16891783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
16991783Sjake	    (u_long)ita);
17092199Sjake	return (&ita->ita_mask);
17189051Sjake}
17289051Sjake
17389051Sjakestatic __inline void *
174100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
17589051Sjake{
17689051Sjake	struct ipi_tlb_args *ita;
17791783Sjake	u_int cpus;
17889051Sjake
17991783Sjake	if (smp_cpus == 1)
18089051Sjake		return (NULL);
18191783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
18291783Sjake		return (NULL);
18389051Sjake	ita = &ipi_tlb_args;
184108187Sjake	mtx_lock_spin(&ipi_mtx);
18592199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
18691783Sjake	ita->ita_pmap = pm;
18789051Sjake	ita->ita_va = va;
18891783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
18992199Sjake	return (&ita->ita_mask);
19089051Sjake}
19189051Sjake
19289051Sjakestatic __inline void *
19391783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
19489051Sjake{
19589051Sjake	struct ipi_tlb_args *ita;
19691783Sjake	u_int cpus;
19789051Sjake
19891783Sjake	if (smp_cpus == 1)
19989051Sjake		return (NULL);
20091783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
20191783Sjake		return (NULL);
20289051Sjake	ita = &ipi_tlb_args;
203108187Sjake	mtx_lock_spin(&ipi_mtx);
20492199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
20591783Sjake	ita->ita_pmap = pm;
20689051Sjake	ita->ita_start = start;
20789051Sjake	ita->ita_end = end;
20891783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita);
20992199Sjake	return (&ita->ita_mask);
21089051Sjake}
21189051Sjake
21289051Sjakestatic __inline void
21389051Sjakeipi_wait(void *cookie)
21489051Sjake{
215143190Salc	volatile u_int *mask;
21689051Sjake
21792199Sjake	if ((mask = cookie) != NULL) {
21892199Sjake		atomic_clear_int(mask, PCPU_GET(cpumask));
21992199Sjake		while (*mask != 0)
22091617Sjake			;
221108187Sjake		mtx_unlock_spin(&ipi_mtx);
22289051Sjake	}
22389051Sjake}
22489051Sjake
225108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
22691783Sjake
22789051Sjake#else
22889051Sjake
22989051Sjakestatic __inline void *
230113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
23197001Sjake{
232169796Smarius
23397001Sjake	return (NULL);
23497001Sjake}
23597001Sjake
23697001Sjakestatic __inline void *
237113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
23897001Sjake{
239169796Smarius
24097001Sjake	return (NULL);
24197001Sjake}
24297001Sjake
24397001Sjakestatic __inline void *
24491783Sjakeipi_tlb_context_demap(struct pmap *pm)
24589051Sjake{
246169796Smarius
24789051Sjake	return (NULL);
24889051Sjake}
24989051Sjake
25089051Sjakestatic __inline void *
251100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
25289051Sjake{
253169796Smarius
25489051Sjake	return (NULL);
25589051Sjake}
25689051Sjake
25789051Sjakestatic __inline void *
25891783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
25989051Sjake{
260169796Smarius
26189051Sjake	return (NULL);
26289051Sjake}
26389051Sjake
26489051Sjakestatic __inline void
26589051Sjakeipi_wait(void *cookie)
26689051Sjake{
267169796Smarius
26889051Sjake}
26989051Sjake
27089051Sjake#endif /* SMP */
27189051Sjake
27289051Sjake#endif /* !LOCORE */
27389051Sjake
27480708Sjake#endif /* !_MACHINE_SMP_H_ */
275