smp.h revision 170846
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 170846 2007-06-16 23:26:00Z marius $
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
42170846Smarius#define	IDR_BUSY			0x0000000000000001ULL
43170846Smarius#define	IDR_NACK			0x0000000000000002ULL
44170846Smarius#define	IDR_CHEETAH_ALL_BUSY		0x5555555555555555ULL
45170846Smarius#define	IDR_CHEETAH_ALL_NACK		(~IDR_CHEETAH_ALL_BUSY)
46170846Smarius#define	IDR_CHEETAH_MAX_BN_PAIRS	32
47170846Smarius#define	IDR_JALAPENO_MAX_BN_PAIRS	4
4889051Sjake
49169796Smarius#define	IDC_ITID_SHIFT			14
50170846Smarius#define	IDC_BN_SHIFT			24
51169796Smarius
5289051Sjake#define	IPI_AST		PIL_AST
5389051Sjake#define	IPI_RENDEZVOUS	PIL_RENDEZVOUS
5489051Sjake#define	IPI_STOP	PIL_STOP
5589051Sjake
56135943Skensmith#define	IPI_RETRIES	5000
5789051Sjake
5889051Sjakestruct cpu_start_args {
5991783Sjake	u_int	csa_count;
6089051Sjake	u_int	csa_mid;
6189051Sjake	u_int	csa_state;
6291783Sjake	vm_offset_t csa_pcpu;
6391617Sjake	u_long	csa_tick;
6491617Sjake	u_long	csa_ver;
6591617Sjake	struct	tte csa_ttes[PCPU_PAGES];
6689051Sjake};
6789051Sjake
6897001Sjakestruct ipi_cache_args {
6997001Sjake	u_int	ica_mask;
70113238Sjake	vm_paddr_t ica_pa;
7197001Sjake};
7297001Sjake
7389051Sjakestruct ipi_tlb_args {
7492199Sjake	u_int	ita_mask;
7591783Sjake	struct	pmap *ita_pmap;
7689051Sjake	u_long	ita_start;
7789051Sjake	u_long	ita_end;
7889051Sjake};
7989051Sjake#define	ita_va	ita_start
8089051Sjake
8189051Sjakestruct pcpu;
8289051Sjake
83152022Sjhbextern struct pcb stoppcbs[];
84152022Sjhb
8589051Sjakevoid	cpu_mp_bootstrap(struct pcpu *pc);
8692199Sjakevoid	cpu_mp_shutdown(void);
8789051Sjake
88170846Smariustypedef	void cpu_ipi_selected_t(u_int, u_long, u_long, u_long);
89170846Smariusextern	cpu_ipi_selected_t *cpu_ipi_selected;
9089051Sjake
9189051Sjakevoid	ipi_selected(u_int cpus, u_int ipi);
9289051Sjakevoid	ipi_all(u_int ipi);
9389051Sjakevoid	ipi_all_but_self(u_int ipi);
9489051Sjake
95170846Smariusvoid	mp_init(void);
9691617Sjake
97108187Sjakeextern	struct mtx ipi_mtx;
98108187Sjakeextern	struct ipi_cache_args ipi_cache_args;
99108187Sjakeextern	struct ipi_tlb_args ipi_tlb_args;
10089051Sjake
10191617Sjakeextern	char *mp_tramp_code;
10291617Sjakeextern	u_long mp_tramp_code_len;
10391617Sjakeextern	u_long mp_tramp_tlb_slots;
10491617Sjakeextern	u_long mp_tramp_func;
10591617Sjake
10691617Sjakeextern	void mp_startup(void);
10791617Sjake
108112399Sjakeextern	char tl_ipi_cheetah_dcache_page_inval[];
109112399Sjakeextern	char tl_ipi_spitfire_dcache_page_inval[];
110112399Sjakeextern	char tl_ipi_spitfire_icache_page_inval[];
111112399Sjake
11289051Sjakeextern	char tl_ipi_level[];
11389051Sjakeextern	char tl_ipi_tlb_context_demap[];
11489051Sjakeextern	char tl_ipi_tlb_page_demap[];
11589051Sjakeextern	char tl_ipi_tlb_range_demap[];
11689051Sjake
11789051Sjake#ifdef SMP
11889051Sjake
119108187Sjake#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
120108187Sjake
12197001Sjakestatic __inline void *
122113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
12397001Sjake{
12497001Sjake	struct ipi_cache_args *ica;
12597001Sjake
12697001Sjake	if (smp_cpus == 1)
12797001Sjake		return (NULL);
12897001Sjake	ica = &ipi_cache_args;
129108187Sjake	mtx_lock_spin(&ipi_mtx);
13097001Sjake	ica->ica_mask = all_cpus;
13197001Sjake	ica->ica_pa = pa;
132112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
13397001Sjake	return (&ica->ica_mask);
13497001Sjake}
13597001Sjake
13697001Sjakestatic __inline void *
137113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
13897001Sjake{
13997001Sjake	struct ipi_cache_args *ica;
14097001Sjake
14197001Sjake	if (smp_cpus == 1)
14297001Sjake		return (NULL);
14397001Sjake	ica = &ipi_cache_args;
144108187Sjake	mtx_lock_spin(&ipi_mtx);
14597001Sjake	ica->ica_mask = all_cpus;
14697001Sjake	ica->ica_pa = pa;
147112399Sjake	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)func, (u_long)ica);
14897001Sjake	return (&ica->ica_mask);
14997001Sjake}
15097001Sjake
15189051Sjakestatic __inline void *
15291783Sjakeipi_tlb_context_demap(struct pmap *pm)
15389051Sjake{
15489051Sjake	struct ipi_tlb_args *ita;
15591783Sjake	u_int cpus;
15689051Sjake
15791783Sjake	if (smp_cpus == 1)
15889051Sjake		return (NULL);
15991783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
16091783Sjake		return (NULL);
16189051Sjake	ita = &ipi_tlb_args;
162108187Sjake	mtx_lock_spin(&ipi_mtx);
16392199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
16491783Sjake	ita->ita_pmap = pm;
16591783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
16691783Sjake	    (u_long)ita);
16792199Sjake	return (&ita->ita_mask);
16889051Sjake}
16989051Sjake
17089051Sjakestatic __inline void *
171100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
17289051Sjake{
17389051Sjake	struct ipi_tlb_args *ita;
17491783Sjake	u_int cpus;
17589051Sjake
17691783Sjake	if (smp_cpus == 1)
17789051Sjake		return (NULL);
17891783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
17991783Sjake		return (NULL);
18089051Sjake	ita = &ipi_tlb_args;
181108187Sjake	mtx_lock_spin(&ipi_mtx);
18292199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
18391783Sjake	ita->ita_pmap = pm;
18489051Sjake	ita->ita_va = va;
18591783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
18692199Sjake	return (&ita->ita_mask);
18789051Sjake}
18889051Sjake
18989051Sjakestatic __inline void *
19091783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
19189051Sjake{
19289051Sjake	struct ipi_tlb_args *ita;
19391783Sjake	u_int cpus;
19489051Sjake
19591783Sjake	if (smp_cpus == 1)
19689051Sjake		return (NULL);
19791783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
19891783Sjake		return (NULL);
19989051Sjake	ita = &ipi_tlb_args;
200108187Sjake	mtx_lock_spin(&ipi_mtx);
20192199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
20291783Sjake	ita->ita_pmap = pm;
20389051Sjake	ita->ita_start = start;
20489051Sjake	ita->ita_end = end;
20591783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita);
20692199Sjake	return (&ita->ita_mask);
20789051Sjake}
20889051Sjake
20989051Sjakestatic __inline void
21089051Sjakeipi_wait(void *cookie)
21189051Sjake{
212143190Salc	volatile u_int *mask;
21389051Sjake
21492199Sjake	if ((mask = cookie) != NULL) {
21592199Sjake		atomic_clear_int(mask, PCPU_GET(cpumask));
21692199Sjake		while (*mask != 0)
21791617Sjake			;
218108187Sjake		mtx_unlock_spin(&ipi_mtx);
21989051Sjake	}
22089051Sjake}
22189051Sjake
222108187Sjake#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
22391783Sjake
22489051Sjake#else
22589051Sjake
22689051Sjakestatic __inline void *
227113238Sjakeipi_dcache_page_inval(void *func, vm_paddr_t pa)
22897001Sjake{
229169796Smarius
23097001Sjake	return (NULL);
23197001Sjake}
23297001Sjake
23397001Sjakestatic __inline void *
234113238Sjakeipi_icache_page_inval(void *func, vm_paddr_t pa)
23597001Sjake{
236169796Smarius
23797001Sjake	return (NULL);
23897001Sjake}
23997001Sjake
24097001Sjakestatic __inline void *
24191783Sjakeipi_tlb_context_demap(struct pmap *pm)
24289051Sjake{
243169796Smarius
24489051Sjake	return (NULL);
24589051Sjake}
24689051Sjake
24789051Sjakestatic __inline void *
248100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
24989051Sjake{
250169796Smarius
25189051Sjake	return (NULL);
25289051Sjake}
25389051Sjake
25489051Sjakestatic __inline void *
25591783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
25689051Sjake{
257169796Smarius
25889051Sjake	return (NULL);
25989051Sjake}
26089051Sjake
26189051Sjakestatic __inline void
26289051Sjakeipi_wait(void *cookie)
26389051Sjake{
264169796Smarius
26589051Sjake}
26689051Sjake
26789051Sjake#endif /* SMP */
26889051Sjake
26989051Sjake#endif /* !LOCORE */
27089051Sjake
27180708Sjake#endif /* !_MACHINE_SMP_H_ */
272