smp.h revision 204152
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 204152 2010-02-20 23:24:19Z 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
59196196Sattilio#define	IPI_STOP_HARD	PIL_STOP
6089051Sjake
61135943Skensmith#define	IPI_RETRIES	5000
6289051Sjake
6389051Sjakestruct cpu_start_args {
6491783Sjake	u_int	csa_count;
6589051Sjake	u_int	csa_mid;
6689051Sjake	u_int	csa_state;
6791783Sjake	vm_offset_t csa_pcpu;
6891617Sjake	u_long	csa_tick;
69182730Smarius	u_long	csa_stick;
7091617Sjake	u_long	csa_ver;
7191617Sjake	struct	tte csa_ttes[PCPU_PAGES];
7289051Sjake};
7389051Sjake
7497001Sjakestruct ipi_cache_args {
7597001Sjake	u_int	ica_mask;
76113238Sjake	vm_paddr_t ica_pa;
7797001Sjake};
7897001Sjake
7989051Sjakestruct ipi_tlb_args {
8092199Sjake	u_int	ita_mask;
8191783Sjake	struct	pmap *ita_pmap;
8289051Sjake	u_long	ita_start;
8389051Sjake	u_long	ita_end;
8489051Sjake};
8589051Sjake#define	ita_va	ita_start
8689051Sjake
8789051Sjakestruct pcpu;
8889051Sjake
89152022Sjhbextern struct pcb stoppcbs[];
90152022Sjhb
9189051Sjakevoid	cpu_mp_bootstrap(struct pcpu *pc);
9292199Sjakevoid	cpu_mp_shutdown(void);
9389051Sjake
94170846Smariustypedef	void cpu_ipi_selected_t(u_int, u_long, u_long, u_long);
95170846Smariusextern	cpu_ipi_selected_t *cpu_ipi_selected;
9689051Sjake
97204152Smariusvoid	mp_init(u_int cpu_impl);
9891617Sjake
99108187Sjakeextern	struct mtx ipi_mtx;
100108187Sjakeextern	struct ipi_cache_args ipi_cache_args;
101108187Sjakeextern	struct ipi_tlb_args ipi_tlb_args;
10289051Sjake
10391617Sjakeextern	char *mp_tramp_code;
10491617Sjakeextern	u_long mp_tramp_code_len;
10591617Sjakeextern	u_long mp_tramp_tlb_slots;
10691617Sjakeextern	u_long mp_tramp_func;
10791617Sjake
10891617Sjakeextern	void mp_startup(void);
10991617Sjake
110112399Sjakeextern	char tl_ipi_cheetah_dcache_page_inval[];
111112399Sjakeextern	char tl_ipi_spitfire_dcache_page_inval[];
112112399Sjakeextern	char tl_ipi_spitfire_icache_page_inval[];
113112399Sjake
11489051Sjakeextern	char tl_ipi_level[];
11589051Sjakeextern	char tl_ipi_tlb_context_demap[];
11689051Sjakeextern	char tl_ipi_tlb_page_demap[];
11789051Sjakeextern	char tl_ipi_tlb_range_demap[];
11889051Sjake
119183142Smariusstatic __inline void
120183142Smariusipi_all_but_self(u_int ipi)
121183142Smarius{
12289051Sjake
123183142Smarius	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi);
124183142Smarius}
125183142Smarius
126183142Smariusstatic __inline void
127183142Smariusipi_selected(u_int cpus, u_int ipi)
128183142Smarius{
129183142Smarius
130183142Smarius	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
131183142Smarius}
132183142Smarius
133108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
134108187Sjake
13597001Sjakestatic __inline void *
136113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
13797001Sjake{
13897001Sjake	struct ipi_cache_args *ica;
13997001Sjake
14097001Sjake	if (smp_cpus == 1)
14197001Sjake		return (NULL);
14297001Sjake	ica = &ipi_cache_args;
143108187Sjake	mtx_lock_spin(&ipi_mtx);
14497001Sjake	ica->ica_mask = all_cpus;
14597001Sjake	ica->ica_pa = pa;
146112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
14797001Sjake	return (&ica->ica_mask);
14897001Sjake}
14997001Sjake
15097001Sjakestatic __inline void *
151113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
15297001Sjake{
15397001Sjake	struct ipi_cache_args *ica;
15497001Sjake
15597001Sjake	if (smp_cpus == 1)
15697001Sjake		return (NULL);
15797001Sjake	ica = &ipi_cache_args;
158108187Sjake	mtx_lock_spin(&ipi_mtx);
15997001Sjake	ica->ica_mask = all_cpus;
16097001Sjake	ica->ica_pa = pa;
161112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
16297001Sjake	return (&ica->ica_mask);
16397001Sjake}
16497001Sjake
16589051Sjakestatic __inline void *
16691783Sjakeipi_tlb_context_demap(struct pmap *pm)
16789051Sjake{
16889051Sjake	struct ipi_tlb_args *ita;
16991783Sjake	u_int cpus;
17089051Sjake
17191783Sjake	if (smp_cpus == 1)
17289051Sjake		return (NULL);
17391783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
17491783Sjake		return (NULL);
17589051Sjake	ita = &ipi_tlb_args;
176108187Sjake	mtx_lock_spin(&ipi_mtx);
17792199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
17891783Sjake	ita->ita_pmap = pm;
17991783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
18091783Sjake	    (u_long)ita);
18192199Sjake	return (&ita->ita_mask);
18289051Sjake}
18389051Sjake
18489051Sjakestatic __inline void *
185100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
18689051Sjake{
18789051Sjake	struct ipi_tlb_args *ita;
18891783Sjake	u_int cpus;
18989051Sjake
19091783Sjake	if (smp_cpus == 1)
19189051Sjake		return (NULL);
19291783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
19391783Sjake		return (NULL);
19489051Sjake	ita = &ipi_tlb_args;
195108187Sjake	mtx_lock_spin(&ipi_mtx);
19692199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
19791783Sjake	ita->ita_pmap = pm;
19889051Sjake	ita->ita_va = va;
19991783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
20092199Sjake	return (&ita->ita_mask);
20189051Sjake}
20289051Sjake
20389051Sjakestatic __inline void *
20491783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
20589051Sjake{
20689051Sjake	struct ipi_tlb_args *ita;
20791783Sjake	u_int cpus;
20889051Sjake
20991783Sjake	if (smp_cpus == 1)
21089051Sjake		return (NULL);
21191783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
21291783Sjake		return (NULL);
21389051Sjake	ita = &ipi_tlb_args;
214108187Sjake	mtx_lock_spin(&ipi_mtx);
21592199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
21691783Sjake	ita->ita_pmap = pm;
21789051Sjake	ita->ita_start = start;
21889051Sjake	ita->ita_end = end;
21991783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita);
22092199Sjake	return (&ita->ita_mask);
22189051Sjake}
22289051Sjake
22389051Sjakestatic __inline void
22489051Sjakeipi_wait(void *cookie)
22589051Sjake{
226143190Salc	volatile u_int *mask;
22789051Sjake
22892199Sjake	if ((mask = cookie) != NULL) {
22992199Sjake		atomic_clear_int(mask, PCPU_GET(cpumask));
23092199Sjake		while (*mask != 0)
23191617Sjake			;
232108187Sjake		mtx_unlock_spin(&ipi_mtx);
23389051Sjake	}
23489051Sjake}
23589051Sjake
236108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
23791783Sjake
238183142Smarius#endif /* !LOCORE */
239183142Smarius
24089051Sjake#else
24189051Sjake
242183142Smarius#ifndef	LOCORE
243183142Smarius
24489051Sjakestatic __inline void *
245113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
24697001Sjake{
247169796Smarius
24897001Sjake	return (NULL);
24997001Sjake}
25097001Sjake
25197001Sjakestatic __inline void *
252113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
25397001Sjake{
254169796Smarius
25597001Sjake	return (NULL);
25697001Sjake}
25797001Sjake
25897001Sjakestatic __inline void *
25991783Sjakeipi_tlb_context_demap(struct pmap *pm)
26089051Sjake{
261169796Smarius
26289051Sjake	return (NULL);
26389051Sjake}
26489051Sjake
26589051Sjakestatic __inline void *
266100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
26789051Sjake{
268169796Smarius
26989051Sjake	return (NULL);
27089051Sjake}
27189051Sjake
27289051Sjakestatic __inline void *
27391783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
27489051Sjake{
275169796Smarius
27689051Sjake	return (NULL);
27789051Sjake}
27889051Sjake
27989051Sjakestatic __inline void
28089051Sjakeipi_wait(void *cookie)
28189051Sjake{
282169796Smarius
28389051Sjake}
28489051Sjake
285183142Smariusstatic __inline void
286183142Smariustl_ipi_cheetah_dcache_page_inval(void)
287183142Smarius{
28889051Sjake
289183142Smarius}
290183142Smarius
291183142Smariusstatic __inline void
292183142Smariustl_ipi_spitfire_dcache_page_inval(void)
293183142Smarius{
294183142Smarius
295183142Smarius}
296183142Smarius
297183142Smariusstatic __inline void
298183142Smariustl_ipi_spitfire_icache_page_inval(void)
299183142Smarius{
300183142Smarius
301183142Smarius}
302183142Smarius
30389051Sjake#endif /* !LOCORE */
30489051Sjake
305183142Smarius#endif /* SMP */
306183142Smarius
30780708Sjake#endif /* !_MACHINE_SMP_H_ */
308