pcpu.h revision 313766
1129198Scognet/*-
2129198Scognet * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
3129198Scognet * All rights reserved.
4129198Scognet *
5129198Scognet * Redistribution and use in source and binary forms, with or without
6129198Scognet * modification, are permitted provided that the following conditions
7129198Scognet * are met:
8129198Scognet * 1. Redistributions of source code must retain the above copyright
9129198Scognet *    notice, this list of conditions and the following disclaimer.
10129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
11129198Scognet *    notice, this list of conditions and the following disclaimer in the
12129198Scognet *    documentation and/or other materials provided with the distribution.
13129198Scognet *
14129198Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15129198Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16129198Scognet * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17129198Scognet * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18129198Scognet * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19129198Scognet * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20129198Scognet * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24129198Scognet * SUCH DAMAGE.
25129198Scognet *
26129198Scognet *	from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
27129198Scognet * $FreeBSD: stable/11/sys/arm/include/pcpu.h 313766 2017-02-15 10:35:46Z jah $
28129198Scognet */
29129198Scognet
30129198Scognet#ifndef	_MACHINE_PCPU_H_
31129198Scognet#define	_MACHINE_PCPU_H_
32129198Scognet
33129198Scognet#ifdef _KERNEL
34129198Scognet
35239268Sgonzo#include <machine/cpuconf.h>
36129198Scognet
37313766Sjah#include <sys/_lock.h>
38313766Sjah#include <sys/_mutex.h>
39313766Sjah
40129198Scognet#define	ALT_STACK_SIZE	128
41129198Scognet
42129198Scognetstruct vmspace;
43129198Scognet
44181875Sjhb#endif	/* _KERNEL */
45181875Sjhb
46284265Sandrew#if __ARM_ARCH >= 6
47313766Sjah
48239268Sgonzo#define PCPU_MD_FIELDS							\
49239268Sgonzo	unsigned int pc_vfpsid;						\
50239268Sgonzo	unsigned int pc_vfpmvfr0;					\
51239268Sgonzo	unsigned int pc_vfpmvfr1;					\
52249265Sglebius	struct pmap *pc_curpmap;					\
53313766Sjah	struct mtx pc_cmap_lock;					\
54313766Sjah	void *pc_cmap1_pte2p;						\
55313766Sjah	void *pc_cmap2_pte2p;						\
56313766Sjah	caddr_t pc_cmap1_addr;						\
57313766Sjah	caddr_t pc_cmap2_addr;						\
58286296Sjah	vm_offset_t pc_qmap_addr;					\
59313766Sjah	void *pc_qmap_pte2p;						\
60294987Szbb	unsigned int pc_dbreg[32];					\
61294987Szbb	int pc_dbreg_cmd;						\
62313766Sjah	char __pad[19]
63239268Sgonzo#else
64249265Sglebius#define PCPU_MD_FIELDS							\
65313766Sjah	char __pad[157]
66239268Sgonzo#endif
67129198Scognet
68181875Sjhb#ifdef _KERNEL
69181875Sjhb
70294987Szbb#define	PC_DBREG_CMD_NONE	0
71294987Szbb#define	PC_DBREG_CMD_LOAD	1
72294987Szbb
73129198Scognetstruct pcb;
74129198Scognetstruct pcpu;
75129198Scognet
76129198Scognetextern struct pcpu *pcpup;
77261415Scognet
78284265Sandrew#if __ARM_ARCH >= 6
79261415Scognet#define CPU_MASK (0xf)
80261415Scognet
81261419Scognet#ifndef SMP
82261419Scognet#define get_pcpu() (pcpup)
83261419Scognet#else
84261415Scognet#define get_pcpu() __extension__ ({			  		\
85261415Scognet    	int id;								\
86261415Scognet        __asm __volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (id));	\
87261415Scognet    	(pcpup + (id & CPU_MASK));					\
88261415Scognet    })
89261419Scognet#endif
90290648Smmel
91261415Scognetstatic inline struct thread *
92261415Scognetget_curthread(void)
93239268Sgonzo{
94261415Scognet	void *ret;
95129198Scognet
96261415Scognet	__asm __volatile("mrc p15, 0, %0, c13, c0, 4" : "=r" (ret));
97261415Scognet	return (ret);
98239268Sgonzo}
99167429Salc
100239268Sgonzostatic inline void
101261415Scognetset_curthread(struct thread *td)
102239268Sgonzo{
103239268Sgonzo
104261415Scognet	__asm __volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (td));
105239268Sgonzo}
106239268Sgonzo
107261415Scognet
108239268Sgonzostatic inline void *
109239268Sgonzoget_tls(void)
110239268Sgonzo{
111239268Sgonzo	void *tls;
112239268Sgonzo
113307136Sed	/* TPIDRURW contains the authoritative value. */
114307136Sed	__asm __volatile("mrc p15, 0, %0, c13, c0, 2" : "=r" (tls));
115239268Sgonzo	return (tls);
116239268Sgonzo}
117239268Sgonzo
118239268Sgonzostatic inline void
119239268Sgonzoset_tls(void *tls)
120239268Sgonzo{
121239268Sgonzo
122307136Sed	/*
123307136Sed	 * Update both TPIDRURW and TPIDRURO. TPIDRURW needs to be written
124307136Sed	 * first to ensure that a context switch between the two writes will
125307136Sed	 * still give the desired result of updating both.
126307136Sed	 */
127307136Sed	__asm __volatile(
128307136Sed	    "mcr p15, 0, %0, c13, c0, 2\n"
129307136Sed	    "mcr p15, 0, %0, c13, c0, 3\n"
130307136Sed	     : : "r" (tls));
131239268Sgonzo}
132261415Scognet
133261415Scognet#define curthread get_curthread()
134261415Scognet
135239268Sgonzo#else
136239268Sgonzo#define get_pcpu()	pcpup
137239268Sgonzo#endif
138239268Sgonzo
139239268Sgonzo#define	PCPU_GET(member)	(get_pcpu()->pc_ ## member)
140239268Sgonzo#define	PCPU_ADD(member, value)	(get_pcpu()->pc_ ## member += (value))
141170388Sjeff#define	PCPU_INC(member)	PCPU_ADD(member, 1)
142245202Scognet#define	PCPU_PTR(member)	(&get_pcpu()->pc_ ## member)
143245202Scognet#define	PCPU_SET(member,value)	(get_pcpu()->pc_ ## member = (value))
144129198Scognet
145239268Sgonzovoid pcpu0_init(void);
146129198Scognet#endif	/* _KERNEL */
147129198Scognet
148129198Scognet#endif	/* !_MACHINE_PCPU_H_ */
149