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 331988 2018-04-04 06:11:05Z mmel $
28129198Scognet */
29129198Scognet
30129198Scognet#ifndef	_MACHINE_PCPU_H_
31129198Scognet#define	_MACHINE_PCPU_H_
32129198Scognet
33129198Scognet#ifdef _KERNEL
34129198Scognet
35313766Sjah#include <sys/_lock.h>
36313766Sjah#include <sys/_mutex.h>
37313766Sjah
38129198Scognet#define	ALT_STACK_SIZE	128
39129198Scognet
40129198Scognetstruct vmspace;
41129198Scognet
42181875Sjhb#endif	/* _KERNEL */
43181875Sjhb
44284265Sandrew#if __ARM_ARCH >= 6
45331988Smmel/* Branch predictor hardening method */
46331988Smmel#define PCPU_BP_HARDEN_KIND_NONE		0
47331988Smmel#define PCPU_BP_HARDEN_KIND_BPIALL		1
48331988Smmel#define PCPU_BP_HARDEN_KIND_ICIALLU		2
49313766Sjah
50239268Sgonzo#define PCPU_MD_FIELDS							\
51239268Sgonzo	unsigned int pc_vfpsid;						\
52239268Sgonzo	unsigned int pc_vfpmvfr0;					\
53239268Sgonzo	unsigned int pc_vfpmvfr1;					\
54249265Sglebius	struct pmap *pc_curpmap;					\
55313766Sjah	struct mtx pc_cmap_lock;					\
56313766Sjah	void *pc_cmap1_pte2p;						\
57313766Sjah	void *pc_cmap2_pte2p;						\
58313766Sjah	caddr_t pc_cmap1_addr;						\
59313766Sjah	caddr_t pc_cmap2_addr;						\
60286296Sjah	vm_offset_t pc_qmap_addr;					\
61313766Sjah	void *pc_qmap_pte2p;						\
62294987Szbb	unsigned int pc_dbreg[32];					\
63294987Szbb	int pc_dbreg_cmd;						\
64331988Smmel	int pc_bp_harden_kind;						\
65331988Smmel	uint32_t pc_original_actlr;					\
66331988Smmel	char __pad[11]
67239268Sgonzo#else
68249265Sglebius#define PCPU_MD_FIELDS							\
69313766Sjah	char __pad[157]
70239268Sgonzo#endif
71129198Scognet
72181875Sjhb#ifdef _KERNEL
73181875Sjhb
74294987Szbb#define	PC_DBREG_CMD_NONE	0
75294987Szbb#define	PC_DBREG_CMD_LOAD	1
76294987Szbb
77129198Scognetstruct pcb;
78129198Scognetstruct pcpu;
79129198Scognet
80129198Scognetextern struct pcpu *pcpup;
81261415Scognet
82284265Sandrew#if __ARM_ARCH >= 6
83261415Scognet#define CPU_MASK (0xf)
84261415Scognet
85261419Scognet#ifndef SMP
86261419Scognet#define get_pcpu() (pcpup)
87261419Scognet#else
88261415Scognet#define get_pcpu() __extension__ ({			  		\
89261415Scognet    	int id;								\
90261415Scognet        __asm __volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (id));	\
91261415Scognet    	(pcpup + (id & CPU_MASK));					\
92261415Scognet    })
93261419Scognet#endif
94290648Smmel
95261415Scognetstatic inline struct thread *
96261415Scognetget_curthread(void)
97239268Sgonzo{
98261415Scognet	void *ret;
99129198Scognet
100261415Scognet	__asm __volatile("mrc p15, 0, %0, c13, c0, 4" : "=r" (ret));
101261415Scognet	return (ret);
102239268Sgonzo}
103167429Salc
104239268Sgonzostatic inline void
105261415Scognetset_curthread(struct thread *td)
106239268Sgonzo{
107239268Sgonzo
108261415Scognet	__asm __volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (td));
109239268Sgonzo}
110239268Sgonzo
111261415Scognet
112239268Sgonzostatic inline void *
113239268Sgonzoget_tls(void)
114239268Sgonzo{
115239268Sgonzo	void *tls;
116239268Sgonzo
117307136Sed	/* TPIDRURW contains the authoritative value. */
118307136Sed	__asm __volatile("mrc p15, 0, %0, c13, c0, 2" : "=r" (tls));
119239268Sgonzo	return (tls);
120239268Sgonzo}
121239268Sgonzo
122239268Sgonzostatic inline void
123239268Sgonzoset_tls(void *tls)
124239268Sgonzo{
125239268Sgonzo
126307136Sed	/*
127307136Sed	 * Update both TPIDRURW and TPIDRURO. TPIDRURW needs to be written
128307136Sed	 * first to ensure that a context switch between the two writes will
129307136Sed	 * still give the desired result of updating both.
130307136Sed	 */
131307136Sed	__asm __volatile(
132307136Sed	    "mcr p15, 0, %0, c13, c0, 2\n"
133307136Sed	    "mcr p15, 0, %0, c13, c0, 3\n"
134307136Sed	     : : "r" (tls));
135239268Sgonzo}
136261415Scognet
137261415Scognet#define curthread get_curthread()
138261415Scognet
139239268Sgonzo#else
140239268Sgonzo#define get_pcpu()	pcpup
141239268Sgonzo#endif
142239268Sgonzo
143239268Sgonzo#define	PCPU_GET(member)	(get_pcpu()->pc_ ## member)
144239268Sgonzo#define	PCPU_ADD(member, value)	(get_pcpu()->pc_ ## member += (value))
145170388Sjeff#define	PCPU_INC(member)	PCPU_ADD(member, 1)
146245202Scognet#define	PCPU_PTR(member)	(&get_pcpu()->pc_ ## member)
147245202Scognet#define	PCPU_SET(member,value)	(get_pcpu()->pc_ ## member = (value))
148129198Scognet
149239268Sgonzovoid pcpu0_init(void);
150129198Scognet#endif	/* _KERNEL */
151129198Scognet
152129198Scognet#endif	/* !_MACHINE_PCPU_H_ */
153