smp.h revision 183142
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 183142 2008-09-18 13:56:30Z 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
4191157Sjake#include <machine/intr_machdep.h>
42169730Skan#include <machine/pcb.h>
4391617Sjake#include <machine/tte.h>
4491157Sjake
45170846Smarius#define	IDR_BUSY			0x0000000000000001ULL
46170846Smarius#define	IDR_NACK			0x0000000000000002ULL
47170846Smarius#define	IDR_CHEETAH_ALL_BUSY		0x5555555555555555ULL
48170846Smarius#define	IDR_CHEETAH_ALL_NACK		(~IDR_CHEETAH_ALL_BUSY)
49170846Smarius#define	IDR_CHEETAH_MAX_BN_PAIRS	32
50170846Smarius#define	IDR_JALAPENO_MAX_BN_PAIRS	4
5189051Sjake
52169796Smarius#define	IDC_ITID_SHIFT			14
53170846Smarius#define	IDC_BN_SHIFT			24
54169796Smarius
5589051Sjake#define	IPI_AST		PIL_AST
5689051Sjake#define	IPI_RENDEZVOUS	PIL_RENDEZVOUS
57178048Smarius#define	IPI_PREEMPT	PIL_PREEMPT
5889051Sjake#define	IPI_STOP	PIL_STOP
5989051Sjake
60135943Skensmith#define	IPI_RETRIES	5000
6189051Sjake
6289051Sjakestruct cpu_start_args {
6391783Sjake	u_int	csa_count;
6489051Sjake	u_int	csa_mid;
6589051Sjake	u_int	csa_state;
6691783Sjake	vm_offset_t csa_pcpu;
6791617Sjake	u_long	csa_tick;
68182730Smarius	u_long	csa_stick;
6991617Sjake	u_long	csa_ver;
7091617Sjake	struct	tte csa_ttes[PCPU_PAGES];
7189051Sjake};
7289051Sjake
7397001Sjakestruct ipi_cache_args {
7497001Sjake	u_int	ica_mask;
75113238Sjake	vm_paddr_t ica_pa;
7697001Sjake};
7797001Sjake
7889051Sjakestruct ipi_tlb_args {
7992199Sjake	u_int	ita_mask;
8091783Sjake	struct	pmap *ita_pmap;
8189051Sjake	u_long	ita_start;
8289051Sjake	u_long	ita_end;
8389051Sjake};
8489051Sjake#define	ita_va	ita_start
8589051Sjake
8689051Sjakestruct pcpu;
8789051Sjake
88152022Sjhbextern struct pcb stoppcbs[];
89152022Sjhb
9089051Sjakevoid	cpu_mp_bootstrap(struct pcpu *pc);
9192199Sjakevoid	cpu_mp_shutdown(void);
9289051Sjake
93170846Smariustypedef	void cpu_ipi_selected_t(u_int, u_long, u_long, u_long);
94170846Smariusextern	cpu_ipi_selected_t *cpu_ipi_selected;
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
118183142Smariusstatic __inline void
119183142Smariusipi_all_but_self(u_int ipi)
120183142Smarius{
12189051Sjake
122183142Smarius	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi);
123183142Smarius}
124183142Smarius
125183142Smariusstatic __inline void
126183142Smariusipi_selected(u_int cpus, u_int ipi)
127183142Smarius{
128183142Smarius
129183142Smarius	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
130183142Smarius}
131183142Smarius
132108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
133108187Sjake
13497001Sjakestatic __inline void *
135113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
13697001Sjake{
13797001Sjake	struct ipi_cache_args *ica;
13897001Sjake
13997001Sjake	if (smp_cpus == 1)
14097001Sjake		return (NULL);
14197001Sjake	ica = &ipi_cache_args;
142108187Sjake	mtx_lock_spin(&ipi_mtx);
14397001Sjake	ica->ica_mask = all_cpus;
14497001Sjake	ica->ica_pa = pa;
145112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
14697001Sjake	return (&ica->ica_mask);
14797001Sjake}
14897001Sjake
14997001Sjakestatic __inline void *
150113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
15197001Sjake{
15297001Sjake	struct ipi_cache_args *ica;
15397001Sjake
15497001Sjake	if (smp_cpus == 1)
15597001Sjake		return (NULL);
15697001Sjake	ica = &ipi_cache_args;
157108187Sjake	mtx_lock_spin(&ipi_mtx);
15897001Sjake	ica->ica_mask = all_cpus;
15997001Sjake	ica->ica_pa = pa;
160112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
16197001Sjake	return (&ica->ica_mask);
16297001Sjake}
16397001Sjake
16489051Sjakestatic __inline void *
16591783Sjakeipi_tlb_context_demap(struct pmap *pm)
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;
17891783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
17991783Sjake	    (u_long)ita);
18092199Sjake	return (&ita->ita_mask);
18189051Sjake}
18289051Sjake
18389051Sjakestatic __inline void *
184100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
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_va = va;
19891783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
19992199Sjake	return (&ita->ita_mask);
20089051Sjake}
20189051Sjake
20289051Sjakestatic __inline void *
20391783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
20489051Sjake{
20589051Sjake	struct ipi_tlb_args *ita;
20691783Sjake	u_int cpus;
20789051Sjake
20891783Sjake	if (smp_cpus == 1)
20989051Sjake		return (NULL);
21091783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
21191783Sjake		return (NULL);
21289051Sjake	ita = &ipi_tlb_args;
213108187Sjake	mtx_lock_spin(&ipi_mtx);
21492199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
21591783Sjake	ita->ita_pmap = pm;
21689051Sjake	ita->ita_start = start;
21789051Sjake	ita->ita_end = end;
21891783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita);
21992199Sjake	return (&ita->ita_mask);
22089051Sjake}
22189051Sjake
22289051Sjakestatic __inline void
22389051Sjakeipi_wait(void *cookie)
22489051Sjake{
225143190Salc	volatile u_int *mask;
22689051Sjake
22792199Sjake	if ((mask = cookie) != NULL) {
22892199Sjake		atomic_clear_int(mask, PCPU_GET(cpumask));
22992199Sjake		while (*mask != 0)
23091617Sjake			;
231108187Sjake		mtx_unlock_spin(&ipi_mtx);
23289051Sjake	}
23389051Sjake}
23489051Sjake
235108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
23691783Sjake
237183142Smarius#endif /* !LOCORE */
238183142Smarius
23989051Sjake#else
24089051Sjake
241183142Smarius#ifndef	LOCORE
242183142Smarius
24389051Sjakestatic __inline void *
244113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
24597001Sjake{
246169796Smarius
24797001Sjake	return (NULL);
24897001Sjake}
24997001Sjake
25097001Sjakestatic __inline void *
251113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
25297001Sjake{
253169796Smarius
25497001Sjake	return (NULL);
25597001Sjake}
25697001Sjake
25797001Sjakestatic __inline void *
25891783Sjakeipi_tlb_context_demap(struct pmap *pm)
25989051Sjake{
260169796Smarius
26189051Sjake	return (NULL);
26289051Sjake}
26389051Sjake
26489051Sjakestatic __inline void *
265100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
26689051Sjake{
267169796Smarius
26889051Sjake	return (NULL);
26989051Sjake}
27089051Sjake
27189051Sjakestatic __inline void *
27291783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
27389051Sjake{
274169796Smarius
27589051Sjake	return (NULL);
27689051Sjake}
27789051Sjake
27889051Sjakestatic __inline void
27989051Sjakeipi_wait(void *cookie)
28089051Sjake{
281169796Smarius
28289051Sjake}
28389051Sjake
284183142Smariusstatic __inline void
285183142Smariustl_ipi_cheetah_dcache_page_inval(void)
286183142Smarius{
28789051Sjake
288183142Smarius}
289183142Smarius
290183142Smariusstatic __inline void
291183142Smariustl_ipi_spitfire_dcache_page_inval(void)
292183142Smarius{
293183142Smarius
294183142Smarius}
295183142Smarius
296183142Smariusstatic __inline void
297183142Smariustl_ipi_spitfire_icache_page_inval(void)
298183142Smarius{
299183142Smarius
300183142Smarius}
301183142Smarius
30289051Sjake#endif /* !LOCORE */
30389051Sjake
304183142Smarius#endif /* SMP */
305183142Smarius
30680708Sjake#endif /* !_MACHINE_SMP_H_ */
307