1a9643ea8Slogwang /*-
2*22ce4affSfengbojiang * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*22ce4affSfengbojiang *
4a9643ea8Slogwang * Copyright (c) 1999 Luoqi Chen <[email protected]>
5a9643ea8Slogwang * All rights reserved.
6a9643ea8Slogwang *
7a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without
8a9643ea8Slogwang * modification, are permitted provided that the following conditions
9a9643ea8Slogwang * are met:
10a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright
11a9643ea8Slogwang * notice, this list of conditions and the following disclaimer.
12a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright
13a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the
14a9643ea8Slogwang * documentation and/or other materials provided with the distribution.
15a9643ea8Slogwang *
16a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26a9643ea8Slogwang * SUCH DAMAGE.
27a9643ea8Slogwang *
28a9643ea8Slogwang * from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
29a9643ea8Slogwang * $FreeBSD$
30a9643ea8Slogwang */
31a9643ea8Slogwang
32a9643ea8Slogwang #ifndef _MACHINE_PCPU_H_
33a9643ea8Slogwang #define _MACHINE_PCPU_H_
34a9643ea8Slogwang
35a9643ea8Slogwang #ifdef _KERNEL
36a9643ea8Slogwang
37*22ce4affSfengbojiang #include <sys/_lock.h>
38*22ce4affSfengbojiang #include <sys/_mutex.h>
39a9643ea8Slogwang
40a9643ea8Slogwang #define ALT_STACK_SIZE 128
41a9643ea8Slogwang
42a9643ea8Slogwang struct vmspace;
43a9643ea8Slogwang
44a9643ea8Slogwang #endif /* _KERNEL */
45a9643ea8Slogwang
46*22ce4affSfengbojiang /* Branch predictor hardening method */
47*22ce4affSfengbojiang #define PCPU_BP_HARDEN_KIND_NONE 0
48*22ce4affSfengbojiang #define PCPU_BP_HARDEN_KIND_BPIALL 1
49*22ce4affSfengbojiang #define PCPU_BP_HARDEN_KIND_ICIALLU 2
50*22ce4affSfengbojiang
51a9643ea8Slogwang #define PCPU_MD_FIELDS \
52a9643ea8Slogwang unsigned int pc_vfpsid; \
53a9643ea8Slogwang unsigned int pc_vfpmvfr0; \
54a9643ea8Slogwang unsigned int pc_vfpmvfr1; \
55a9643ea8Slogwang struct pmap *pc_curpmap; \
56*22ce4affSfengbojiang struct mtx pc_cmap_lock; \
57*22ce4affSfengbojiang void *pc_cmap1_pte2p; \
58*22ce4affSfengbojiang void *pc_cmap2_pte2p; \
59*22ce4affSfengbojiang caddr_t pc_cmap1_addr; \
60*22ce4affSfengbojiang caddr_t pc_cmap2_addr; \
61a9643ea8Slogwang vm_offset_t pc_qmap_addr; \
62*22ce4affSfengbojiang void *pc_qmap_pte2p; \
63a9643ea8Slogwang unsigned int pc_dbreg[32]; \
64a9643ea8Slogwang int pc_dbreg_cmd; \
65*22ce4affSfengbojiang int pc_bp_harden_kind; \
66*22ce4affSfengbojiang uint32_t pc_original_actlr; \
67*22ce4affSfengbojiang uint64_t pc_clock; \
68*22ce4affSfengbojiang uint32_t pc_mpidr; \
69*22ce4affSfengbojiang char __pad[135]
70a9643ea8Slogwang
71a9643ea8Slogwang #ifdef _KERNEL
72a9643ea8Slogwang
73a9643ea8Slogwang #define PC_DBREG_CMD_NONE 0
74a9643ea8Slogwang #define PC_DBREG_CMD_LOAD 1
75a9643ea8Slogwang
76a9643ea8Slogwang struct pcb;
77a9643ea8Slogwang struct pcpu;
78a9643ea8Slogwang
79a9643ea8Slogwang extern struct pcpu *pcpup;
80a9643ea8Slogwang
81a9643ea8Slogwang #define CPU_MASK (0xf)
82a9643ea8Slogwang
83a9643ea8Slogwang #ifndef SMP
84a9643ea8Slogwang #define get_pcpu() (pcpup)
85a9643ea8Slogwang #else
86a9643ea8Slogwang #define get_pcpu() __extension__ ({ \
87a9643ea8Slogwang int id; \
88a9643ea8Slogwang __asm __volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (id)); \
89a9643ea8Slogwang (pcpup + (id & CPU_MASK)); \
90a9643ea8Slogwang })
91a9643ea8Slogwang #endif
92a9643ea8Slogwang
93a9643ea8Slogwang static inline struct thread *
get_curthread(void)94a9643ea8Slogwang get_curthread(void)
95a9643ea8Slogwang {
96a9643ea8Slogwang void *ret;
97a9643ea8Slogwang
98a9643ea8Slogwang __asm __volatile("mrc p15, 0, %0, c13, c0, 4" : "=r" (ret));
99a9643ea8Slogwang return (ret);
100a9643ea8Slogwang }
101a9643ea8Slogwang
102a9643ea8Slogwang static inline void
set_curthread(struct thread * td)103a9643ea8Slogwang set_curthread(struct thread *td)
104a9643ea8Slogwang {
105a9643ea8Slogwang
106a9643ea8Slogwang __asm __volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (td));
107a9643ea8Slogwang }
108a9643ea8Slogwang
109a9643ea8Slogwang static inline void *
get_tls(void)110a9643ea8Slogwang get_tls(void)
111a9643ea8Slogwang {
112a9643ea8Slogwang void *tls;
113a9643ea8Slogwang
114*22ce4affSfengbojiang /* TPIDRURW contains the authoritative value. */
115*22ce4affSfengbojiang __asm __volatile("mrc p15, 0, %0, c13, c0, 2" : "=r" (tls));
116a9643ea8Slogwang return (tls);
117a9643ea8Slogwang }
118a9643ea8Slogwang
119a9643ea8Slogwang static inline void
set_tls(void * tls)120a9643ea8Slogwang set_tls(void *tls)
121a9643ea8Slogwang {
122a9643ea8Slogwang
123*22ce4affSfengbojiang /*
124*22ce4affSfengbojiang * Update both TPIDRURW and TPIDRURO. TPIDRURW needs to be written
125*22ce4affSfengbojiang * first to ensure that a context switch between the two writes will
126*22ce4affSfengbojiang * still give the desired result of updating both.
127*22ce4affSfengbojiang */
128*22ce4affSfengbojiang __asm __volatile(
129*22ce4affSfengbojiang "mcr p15, 0, %0, c13, c0, 2\n"
130*22ce4affSfengbojiang "mcr p15, 0, %0, c13, c0, 3\n"
131*22ce4affSfengbojiang : : "r" (tls));
132a9643ea8Slogwang }
133a9643ea8Slogwang
134a9643ea8Slogwang #define curthread get_curthread()
135a9643ea8Slogwang
136a9643ea8Slogwang
137a9643ea8Slogwang #define PCPU_GET(member) (get_pcpu()->pc_ ## member)
138a9643ea8Slogwang #define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))
139a9643ea8Slogwang #define PCPU_INC(member) PCPU_ADD(member, 1)
140a9643ea8Slogwang #define PCPU_PTR(member) (&get_pcpu()->pc_ ## member)
141a9643ea8Slogwang #define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value))
142a9643ea8Slogwang
143a9643ea8Slogwang void pcpu0_init(void);
144a9643ea8Slogwang #endif /* _KERNEL */
145a9643ea8Slogwang
146a9643ea8Slogwang #endif /* !_MACHINE_PCPU_H_ */
147