smp.h revision 100718
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 100718 2002-07-26 15:54:04Z jake $
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>
3991617Sjake#include <machine/tte.h>
4091157Sjake
4189051Sjake#define	IDR_BUSY	(1<<0)
4289051Sjake#define	IDR_NACK	(1<<1)
4389051Sjake
4489051Sjake#define	IPI_AST		PIL_AST
4589051Sjake#define	IPI_RENDEZVOUS	PIL_RENDEZVOUS
4689051Sjake#define	IPI_STOP	PIL_STOP
4789051Sjake
4889051Sjake#define	IPI_RETRIES	100
4989051Sjake
5089051Sjakestruct cpu_start_args {
5191783Sjake	u_int	csa_count;
5289051Sjake	u_int	csa_mid;
5389051Sjake	u_int	csa_state;
5491783Sjake	vm_offset_t csa_pcpu;
5591617Sjake	u_long	csa_tick;
5691617Sjake	u_long	csa_ver;
5791617Sjake	struct	tte csa_ttes[PCPU_PAGES];
5889051Sjake};
5989051Sjake
6097001Sjakestruct ipi_cache_args {
6197001Sjake	u_int	ica_mask;
6297001Sjake	u_long	ica_pa;
6397001Sjake};
6497001Sjake
6589051Sjakestruct ipi_tlb_args {
6692199Sjake	u_int	ita_mask;
6791783Sjake	struct	pmap *ita_pmap;
6889051Sjake	u_long	ita_start;
6989051Sjake	u_long	ita_end;
7089051Sjake};
7189051Sjake#define	ita_va	ita_start
7289051Sjake
7389051Sjakestruct pcpu;
7489051Sjake
7589051Sjakevoid	cpu_mp_bootstrap(struct pcpu *pc);
7692199Sjakevoid	cpu_mp_shutdown(void);
7789051Sjake
7889051Sjakevoid	cpu_ipi_selected(u_int cpus, u_long d0, u_long d1, u_long d2);
7989051Sjakevoid	cpu_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2);
8089051Sjake
8189051Sjakevoid	ipi_selected(u_int cpus, u_int ipi);
8289051Sjakevoid	ipi_all(u_int ipi);
8389051Sjakevoid	ipi_all_but_self(u_int ipi);
8489051Sjake
8591617Sjakevm_offset_t mp_tramp_alloc(void);
8691617Sjake
8797001Sjakeextern	struct	ipi_cache_args ipi_cache_args;
8889425Sjakeextern	struct	ipi_level_args ipi_level_args;
8989425Sjakeextern	struct	ipi_tlb_args ipi_tlb_args;
9089051Sjake
9191617Sjakeextern	vm_offset_t mp_tramp;
9291617Sjakeextern	char *mp_tramp_code;
9391617Sjakeextern	u_long mp_tramp_code_len;
9491617Sjakeextern	u_long mp_tramp_tlb_slots;
9591617Sjakeextern	u_long mp_tramp_func;
9691617Sjake
9791617Sjakeextern	void mp_startup(void);
9891617Sjake
9997001Sjakeextern	char tl_ipi_dcache_page_inval[];
10097001Sjakeextern	char tl_ipi_icache_page_inval[];
10189051Sjakeextern	char tl_ipi_level[];
10289051Sjakeextern	char tl_ipi_tlb_context_demap[];
10389051Sjakeextern	char tl_ipi_tlb_page_demap[];
10489051Sjakeextern	char tl_ipi_tlb_range_demap[];
10589051Sjake
10689051Sjake#ifdef SMP
10789051Sjake
10897001Sjakestatic __inline void *
10997001Sjakeipi_dcache_page_inval(vm_offset_t pa)
11097001Sjake{
11197001Sjake	struct ipi_cache_args *ica;
11297001Sjake
11397001Sjake	if (smp_cpus == 1)
11497001Sjake		return (NULL);
11597001Sjake	ica = &ipi_cache_args;
11697001Sjake	ica->ica_mask = all_cpus;
11797001Sjake	ica->ica_pa = pa;
11899879Stmm	cpu_ipi_selected(PCPU_GET(other_cpus), 0,
11999879Stmm	    (u_long)tl_ipi_dcache_page_inval, (u_long)ica);
12097001Sjake	return (&ica->ica_mask);
12197001Sjake}
12297001Sjake
12397001Sjakestatic __inline void *
12497001Sjakeipi_icache_page_inval(vm_offset_t pa)
12597001Sjake{
12697001Sjake	struct ipi_cache_args *ica;
12797001Sjake
12897001Sjake	if (smp_cpus == 1)
12997001Sjake		return (NULL);
13097001Sjake	ica = &ipi_cache_args;
13197001Sjake	ica->ica_mask = all_cpus;
13297001Sjake	ica->ica_pa = pa;
13399879Stmm	cpu_ipi_selected(PCPU_GET(other_cpus), 0,
13499879Stmm	    (u_long)tl_ipi_icache_page_inval, (u_long)ica);
13597001Sjake	return (&ica->ica_mask);
13697001Sjake}
13797001Sjake
13891783Sjake#ifdef _MACHINE_PMAP_H_
13991783Sjake
14089051Sjakestatic __inline void *
14191783Sjakeipi_tlb_context_demap(struct pmap *pm)
14289051Sjake{
14389051Sjake	struct ipi_tlb_args *ita;
14491783Sjake	u_int cpus;
14589051Sjake
14691783Sjake	if (smp_cpus == 1)
14789051Sjake		return (NULL);
14891783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
14991783Sjake		return (NULL);
15089051Sjake	ita = &ipi_tlb_args;
15192199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
15291783Sjake	ita->ita_pmap = pm;
15391783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_context_demap,
15491783Sjake	    (u_long)ita);
15592199Sjake	return (&ita->ita_mask);
15689051Sjake}
15789051Sjake
15889051Sjakestatic __inline void *
159100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
16089051Sjake{
16189051Sjake	struct ipi_tlb_args *ita;
16291783Sjake	u_int cpus;
16389051Sjake
16491783Sjake	if (smp_cpus == 1)
16589051Sjake		return (NULL);
16691783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
16791783Sjake		return (NULL);
16889051Sjake	ita = &ipi_tlb_args;
16992199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
17091783Sjake	ita->ita_pmap = pm;
17189051Sjake	ita->ita_va = va;
17291783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_page_demap, (u_long)ita);
17392199Sjake	return (&ita->ita_mask);
17489051Sjake}
17589051Sjake
17689051Sjakestatic __inline void *
17791783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
17889051Sjake{
17989051Sjake	struct ipi_tlb_args *ita;
18091783Sjake	u_int cpus;
18189051Sjake
18291783Sjake	if (smp_cpus == 1)
18389051Sjake		return (NULL);
18491783Sjake	if ((cpus = (pm->pm_active & PCPU_GET(other_cpus))) == 0)
18591783Sjake		return (NULL);
18689051Sjake	ita = &ipi_tlb_args;
18792199Sjake	ita->ita_mask = cpus | PCPU_GET(cpumask);
18891783Sjake	ita->ita_pmap = pm;
18989051Sjake	ita->ita_start = start;
19089051Sjake	ita->ita_end = end;
19191783Sjake	cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_tlb_range_demap, (u_long)ita);
19292199Sjake	return (&ita->ita_mask);
19389051Sjake}
19489051Sjake
19589051Sjakestatic __inline void
19689051Sjakeipi_wait(void *cookie)
19789051Sjake{
19892199Sjake	u_int *volatile mask;
19989051Sjake
20092199Sjake	if ((mask = cookie) != NULL) {
20192199Sjake		atomic_clear_int(mask, PCPU_GET(cpumask));
20292199Sjake		while (*mask != 0)
20391617Sjake			;
20489051Sjake	}
20589051Sjake}
20689051Sjake
20791783Sjake#endif
20891783Sjake
20989051Sjake#else
21089051Sjake
21189051Sjakestatic __inline void *
21297001Sjakeipi_dcache_page_inval(vm_offset_t pa)
21397001Sjake{
21497001Sjake	return (NULL);
21597001Sjake}
21697001Sjake
21797001Sjakestatic __inline void *
21897001Sjakeipi_icache_page_inval(vm_offset_t pa)
21997001Sjake{
22097001Sjake	return (NULL);
22197001Sjake}
22297001Sjake
22397001Sjakestatic __inline void *
22491783Sjakeipi_tlb_context_demap(struct pmap *pm)
22589051Sjake{
22689051Sjake	return (NULL);
22789051Sjake}
22889051Sjake
22989051Sjakestatic __inline void *
230100718Sjakeipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
23189051Sjake{
23289051Sjake	return (NULL);
23389051Sjake}
23489051Sjake
23589051Sjakestatic __inline void *
23691783Sjakeipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
23789051Sjake{
23889051Sjake	return (NULL);
23989051Sjake}
24089051Sjake
24189051Sjakestatic __inline void
24289051Sjakeipi_wait(void *cookie)
24389051Sjake{
24489051Sjake}
24589051Sjake
24689051Sjake#endif /* SMP */
24789051Sjake
24889051Sjake#endif /* !LOCORE */
24989051Sjake
25080708Sjake#endif /* !_MACHINE_SMP_H_ */
251