| @@ -1,382 +1,385 @@ | | | @@ -1,382 +1,385 @@ |
1 | /* $NetBSD: cpu.h,v 1.93 2010/12/26 12:06:57 martin Exp $ */ | | 1 | /* $NetBSD: cpu.h,v 1.94 2011/01/24 10:04:28 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1992, 1993 | | 4 | * Copyright (c) 1992, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This software was developed by the Computer Systems Engineering group | | 7 | * This software was developed by the Computer Systems Engineering group |
8 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and | | 8 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and |
9 | * contributed to Berkeley. | | 9 | * contributed to Berkeley. |
10 | * | | 10 | * |
11 | * All advertising materials mentioning features or use of this software | | 11 | * All advertising materials mentioning features or use of this software |
12 | * must display the following acknowledgement: | | 12 | * must display the following acknowledgement: |
13 | * This product includes software developed by the University of | | 13 | * This product includes software developed by the University of |
14 | * California, Lawrence Berkeley Laboratory. | | 14 | * California, Lawrence Berkeley Laboratory. |
15 | * | | 15 | * |
16 | * Redistribution and use in source and binary forms, with or without | | 16 | * Redistribution and use in source and binary forms, with or without |
17 | * modification, are permitted provided that the following conditions | | 17 | * modification, are permitted provided that the following conditions |
18 | * are met: | | 18 | * are met: |
19 | * 1. Redistributions of source code must retain the above copyright | | 19 | * 1. Redistributions of source code must retain the above copyright |
20 | * notice, this list of conditions and the following disclaimer. | | 20 | * notice, this list of conditions and the following disclaimer. |
21 | * 2. Redistributions in binary form must reproduce the above copyright | | 21 | * 2. Redistributions in binary form must reproduce the above copyright |
22 | * notice, this list of conditions and the following disclaimer in the | | 22 | * notice, this list of conditions and the following disclaimer in the |
23 | * documentation and/or other materials provided with the distribution. | | 23 | * documentation and/or other materials provided with the distribution. |
24 | * 3. Neither the name of the University nor the names of its contributors | | 24 | * 3. Neither the name of the University nor the names of its contributors |
25 | * may be used to endorse or promote products derived from this software | | 25 | * may be used to endorse or promote products derived from this software |
26 | * without specific prior written permission. | | 26 | * without specific prior written permission. |
27 | * | | 27 | * |
28 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 28 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
29 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 29 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
30 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 30 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
31 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 31 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
32 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 32 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
38 | * SUCH DAMAGE. | | 38 | * SUCH DAMAGE. |
39 | * | | 39 | * |
40 | * @(#)cpu.h 8.4 (Berkeley) 1/5/94 | | 40 | * @(#)cpu.h 8.4 (Berkeley) 1/5/94 |
41 | */ | | 41 | */ |
42 | | | 42 | |
43 | #ifndef _CPU_H_ | | 43 | #ifndef _CPU_H_ |
44 | #define _CPU_H_ | | 44 | #define _CPU_H_ |
45 | | | 45 | |
46 | /* | | 46 | /* |
47 | * CTL_MACHDEP definitions. | | 47 | * CTL_MACHDEP definitions. |
48 | */ | | 48 | */ |
49 | #define CPU_BOOTED_KERNEL 1 /* string: booted kernel name */ | | 49 | #define CPU_BOOTED_KERNEL 1 /* string: booted kernel name */ |
50 | #define CPU_BOOTED_DEVICE 2 /* string: device booted from */ | | 50 | #define CPU_BOOTED_DEVICE 2 /* string: device booted from */ |
51 | #define CPU_BOOT_ARGS 3 /* string: args booted with */ | | 51 | #define CPU_BOOT_ARGS 3 /* string: args booted with */ |
52 | #define CPU_ARCH 4 /* integer: cpu architecture version */ | | 52 | #define CPU_ARCH 4 /* integer: cpu architecture version */ |
53 | #define CPU_MAXID 5 /* number of valid machdep ids */ | | 53 | #define CPU_MAXID 5 /* number of valid machdep ids */ |
54 | | | 54 | |
55 | #ifdef _KERNEL | | 55 | #ifdef _KERNEL |
56 | /* | | 56 | /* |
57 | * Exported definitions unique to SPARC cpu support. | | 57 | * Exported definitions unique to SPARC cpu support. |
58 | */ | | 58 | */ |
59 | | | 59 | |
60 | #if defined(_KERNEL_OPT) | | 60 | #if defined(_KERNEL_OPT) |
61 | #include "opt_multiprocessor.h" | | 61 | #include "opt_multiprocessor.h" |
62 | #include "opt_lockdebug.h" | | 62 | #include "opt_lockdebug.h" |
63 | #endif | | 63 | #endif |
64 | | | 64 | |
65 | #include <machine/psl.h> | | 65 | #include <machine/psl.h> |
66 | #include <machine/reg.h> | | 66 | #include <machine/reg.h> |
67 | #include <machine/pte.h> | | 67 | #include <machine/pte.h> |
68 | #include <machine/intr.h> | | 68 | #include <machine/intr.h> |
69 | #include <machine/cpuset.h> | | 69 | #include <machine/cpuset.h> |
70 | #include <sparc64/sparc64/intreg.h> | | 70 | #include <sparc64/sparc64/intreg.h> |
71 | | | 71 | |
72 | #include <sys/cpu_data.h> | | 72 | #include <sys/cpu_data.h> |
73 | #include <sys/evcnt.h> | | 73 | #include <sys/evcnt.h> |
74 | /* | | 74 | /* |
75 | * The cpu_info structure is part of a 64KB structure mapped both the kernel | | 75 | * The cpu_info structure is part of a 64KB structure mapped both the kernel |
76 | * pmap and a single locked TTE a CPUINFO_VA for that particular processor. | | 76 | * pmap and a single locked TTE a CPUINFO_VA for that particular processor. |
77 | * Each processor's cpu_info is accessible at CPUINFO_VA only for that | | 77 | * Each processor's cpu_info is accessible at CPUINFO_VA only for that |
78 | * processor. Other processors can access that through an additional mapping | | 78 | * processor. Other processors can access that through an additional mapping |
79 | * in the kernel pmap. | | 79 | * in the kernel pmap. |
80 | * | | 80 | * |
81 | * The 64KB page contains: | | 81 | * The 64KB page contains: |
82 | * | | 82 | * |
83 | * cpu_info | | 83 | * cpu_info |
84 | * interrupt stack (all remaining space) | | 84 | * interrupt stack (all remaining space) |
85 | * idle PCB | | 85 | * idle PCB |
86 | * idle stack (STACKSPACE - sizeof(PCB)) | | 86 | * idle stack (STACKSPACE - sizeof(PCB)) |
87 | * 32KB TSB | | 87 | * 32KB TSB |
88 | */ | | 88 | */ |
89 | | | 89 | |
90 | struct cpu_info { | | 90 | struct cpu_info { |
91 | struct cpu_data ci_data; /* MI per-cpu data */ | | 91 | struct cpu_data ci_data; /* MI per-cpu data */ |
92 | | | 92 | |
93 | | | 93 | |
94 | /* | | 94 | /* |
95 | * SPARC cpu_info structures live at two VAs: one global | | 95 | * SPARC cpu_info structures live at two VAs: one global |
96 | * VA (so each CPU can access any other CPU's cpu_info) | | 96 | * VA (so each CPU can access any other CPU's cpu_info) |
97 | * and an alias VA CPUINFO_VA which is the same on each | | 97 | * and an alias VA CPUINFO_VA which is the same on each |
98 | * CPU and maps to that CPU's cpu_info. Since the alias | | 98 | * CPU and maps to that CPU's cpu_info. Since the alias |
99 | * CPUINFO_VA is how we locate our cpu_info, we have to | | 99 | * CPUINFO_VA is how we locate our cpu_info, we have to |
100 | * self-reference the global VA so that we can return it | | 100 | * self-reference the global VA so that we can return it |
101 | * in the curcpu() macro. | | 101 | * in the curcpu() macro. |
102 | */ | | 102 | */ |
103 | struct cpu_info * volatile ci_self; | | 103 | struct cpu_info * volatile ci_self; |
104 | | | 104 | |
105 | /* Most important fields first */ | | 105 | /* Most important fields first */ |
106 | struct lwp *ci_curlwp; | | 106 | struct lwp *ci_curlwp; |
107 | struct pcb *ci_cpcb; | | 107 | struct pcb *ci_cpcb; |
108 | struct cpu_info *ci_next; | | 108 | struct cpu_info *ci_next; |
109 | | | 109 | |
110 | struct lwp *ci_fplwp; | | 110 | struct lwp *ci_fplwp; |
111 | | | 111 | |
112 | void *ci_eintstack; | | 112 | void *ci_eintstack; |
113 | | | 113 | |
114 | int ci_mtx_count; | | 114 | int ci_mtx_count; |
115 | int ci_mtx_oldspl; | | 115 | int ci_mtx_oldspl; |
116 | | | 116 | |
117 | /* Spinning up the CPU */ | | 117 | /* Spinning up the CPU */ |
118 | void (*ci_spinup)(void); | | 118 | void (*ci_spinup)(void); |
119 | paddr_t ci_paddr; | | 119 | paddr_t ci_paddr; |
120 | | | 120 | |
121 | int ci_cpuid; | | 121 | int ci_cpuid; |
122 | | | 122 | |
123 | /* CPU PROM information. */ | | 123 | /* CPU PROM information. */ |
124 | u_int ci_node; | | 124 | u_int ci_node; |
125 | | | 125 | |
126 | /* %tick and cpu frequency information */ | | 126 | /* %tick and cpu frequency information */ |
127 | u_long ci_tick_increment; | | 127 | u_long ci_tick_increment; |
128 | uint64_t ci_cpu_clockrate[2]; | | 128 | uint64_t ci_cpu_clockrate[2]; |
129 | | | 129 | |
130 | /* Interrupts */ | | 130 | /* Interrupts */ |
131 | struct intrhand *ci_intrpending[16]; | | 131 | struct intrhand *ci_intrpending[16]; |
132 | struct intrhand *ci_tick_ih; | | 132 | struct intrhand *ci_tick_ih; |
133 | | | 133 | |
134 | /* Event counters */ | | 134 | /* Event counters */ |
135 | struct evcnt ci_tick_evcnt; | | 135 | struct evcnt ci_tick_evcnt; |
136 | | | 136 | |
137 | /* This could be under MULTIPROCESSOR, but there's no good reason */ | | 137 | /* This could be under MULTIPROCESSOR, but there's no good reason */ |
138 | struct evcnt ci_ipi_evcnt[IPI_EVCNT_NUM]; | | 138 | struct evcnt ci_ipi_evcnt[IPI_EVCNT_NUM]; |
139 | | | 139 | |
140 | int ci_flags; | | 140 | int ci_flags; |
141 | int ci_want_ast; | | 141 | int ci_want_ast; |
142 | int ci_want_resched; | | 142 | int ci_want_resched; |
143 | int ci_idepth; | | 143 | int ci_idepth; |
144 | | | 144 | |
145 | /* | | 145 | /* |
146 | * A context is simply a small number that differentiates multiple mappings | | 146 | * A context is simply a small number that differentiates multiple mappings |
147 | * of the same address. Contexts on the spitfire are 13 bits, but could | | 147 | * of the same address. Contexts on the spitfire are 13 bits, but could |
148 | * be as large as 17 bits. | | 148 | * be as large as 17 bits. |
149 | * | | 149 | * |
150 | * Each context is either free or attached to a pmap. | | 150 | * Each context is either free or attached to a pmap. |
151 | * | | 151 | * |
152 | * The context table is an array of pointers to psegs. Just dereference | | 152 | * The context table is an array of pointers to psegs. Just dereference |
153 | * the right pointer and you get to the pmap segment tables. These are | | 153 | * the right pointer and you get to the pmap segment tables. These are |
154 | * physical addresses, of course. | | 154 | * physical addresses, of course. |
155 | * | | 155 | * |
156 | * ci_ctx_lock protects this CPUs context allocation/free. | | 156 | * ci_ctx_lock protects this CPUs context allocation/free. |
157 | * These are all allocated almost with in the same cacheline. | | 157 | * These are all allocated almost with in the same cacheline. |
158 | */ | | 158 | */ |
159 | kmutex_t ci_ctx_lock; | | 159 | kmutex_t ci_ctx_lock; |
160 | int ci_pmap_next_ctx; | | 160 | int ci_pmap_next_ctx; |
161 | int ci_numctx; | | 161 | int ci_numctx; |
162 | paddr_t *ci_ctxbusy; | | 162 | paddr_t *ci_ctxbusy; |
163 | LIST_HEAD(, pmap) ci_pmap_ctxlist; | | 163 | LIST_HEAD(, pmap) ci_pmap_ctxlist; |
164 | | | 164 | |
165 | /* | | 165 | /* |
166 | * The TSBs are per cpu too (since MMU context differs between | | 166 | * The TSBs are per cpu too (since MMU context differs between |
167 | * cpus). These are just caches for the TLBs. | | 167 | * cpus). These are just caches for the TLBs. |
168 | */ | | 168 | */ |
169 | pte_t *ci_tsb_dmmu; | | 169 | pte_t *ci_tsb_dmmu; |
170 | pte_t *ci_tsb_immu; | | 170 | pte_t *ci_tsb_immu; |
171 | | | 171 | |
172 | volatile void *ci_ddb_regs; /* DDB regs */ | | 172 | volatile void *ci_ddb_regs; /* DDB regs */ |
173 | }; | | 173 | }; |
174 | | | 174 | |
175 | #define CPUF_PRIMARY 1 | | 175 | #define CPUF_PRIMARY 1 |
176 | | | 176 | |
177 | /* | | 177 | /* |
178 | * CPU boot arguments. Used by secondary CPUs at the bootstrap time. | | 178 | * CPU boot arguments. Used by secondary CPUs at the bootstrap time. |
179 | */ | | 179 | */ |
180 | struct cpu_bootargs { | | 180 | struct cpu_bootargs { |
181 | u_int cb_node; /* PROM CPU node */ | | 181 | u_int cb_node; /* PROM CPU node */ |
182 | volatile int cb_flags; | | 182 | volatile int cb_flags; |
183 | | | 183 | |
184 | vaddr_t cb_ktext; | | 184 | vaddr_t cb_ktext; |
185 | paddr_t cb_ktextp; | | 185 | paddr_t cb_ktextp; |
186 | vaddr_t cb_ektext; | | 186 | vaddr_t cb_ektext; |
187 | | | 187 | |
188 | vaddr_t cb_kdata; | | 188 | vaddr_t cb_kdata; |
189 | paddr_t cb_kdatap; | | 189 | paddr_t cb_kdatap; |
190 | vaddr_t cb_ekdata; | | 190 | vaddr_t cb_ekdata; |
191 | | | 191 | |
192 | paddr_t cb_cpuinfo; | | 192 | paddr_t cb_cpuinfo; |
193 | }; | | 193 | }; |
194 | | | 194 | |
195 | extern struct cpu_bootargs *cpu_args; | | 195 | extern struct cpu_bootargs *cpu_args; |
196 | | | 196 | |
197 | #if defined(MULTIPROCESSOR) | | 197 | #if defined(MULTIPROCESSOR) |
198 | extern int sparc_ncpus; | | 198 | extern int sparc_ncpus; |
199 | #else | | 199 | #else |
200 | #define sparc_ncpus 1 | | 200 | #define sparc_ncpus 1 |
201 | #endif | | 201 | #endif |
202 | | | 202 | |
203 | extern struct cpu_info *cpus; | | 203 | extern struct cpu_info *cpus; |
204 | extern struct pool_cache *fpstate_cache; | | 204 | extern struct pool_cache *fpstate_cache; |
205 | | | 205 | |
206 | #define curcpu() (((struct cpu_info *)CPUINFO_VA)->ci_self) | | 206 | #define curcpu() (((struct cpu_info *)CPUINFO_VA)->ci_self) |
207 | #define cpu_number() (curcpu()->ci_index) | | 207 | #define cpu_number() (curcpu()->ci_index) |
208 | #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY) | | 208 | #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY) |
209 | | | 209 | |
210 | #define CPU_INFO_ITERATOR int | | 210 | #define CPU_INFO_ITERATOR int |
211 | #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = cpus; ci != NULL; \ | | 211 | #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = cpus; ci != NULL; \ |
212 | ci = ci->ci_next | | 212 | ci = ci->ci_next |
213 | | | 213 | |
214 | #define curlwp curcpu()->ci_curlwp | | 214 | #define curlwp curcpu()->ci_curlwp |
215 | #define fplwp curcpu()->ci_fplwp | | 215 | #define fplwp curcpu()->ci_fplwp |
216 | #define curpcb curcpu()->ci_cpcb | | 216 | #define curpcb curcpu()->ci_cpcb |
217 | | | 217 | |
218 | #define want_ast curcpu()->ci_want_ast | | 218 | #define want_ast curcpu()->ci_want_ast |
219 | #define want_resched curcpu()->ci_want_resched | | 219 | #define want_resched curcpu()->ci_want_resched |
220 | | | 220 | |
221 | /* | | 221 | /* |
222 | * definitions of cpu-dependent requirements | | 222 | * definitions of cpu-dependent requirements |
223 | * referenced in generic code | | 223 | * referenced in generic code |
224 | */ | | 224 | */ |
225 | #define cpu_wait(p) /* nothing */ | | 225 | #define cpu_wait(p) /* nothing */ |
226 | void cpu_proc_fork(struct proc *, struct proc *); | | 226 | void cpu_proc_fork(struct proc *, struct proc *); |
227 | | | 227 | |
228 | /* run on the cpu itself */ | | 228 | /* run on the cpu itself */ |
229 | void cpu_pmap_init(struct cpu_info *); | | 229 | void cpu_pmap_init(struct cpu_info *); |
230 | /* run upfront to prepare the cpu_info */ | | 230 | /* run upfront to prepare the cpu_info */ |
231 | void cpu_pmap_prepare(struct cpu_info *, bool); | | 231 | void cpu_pmap_prepare(struct cpu_info *, bool); |
232 | | | 232 | |
233 | #if defined(MULTIPROCESSOR) | | 233 | #if defined(MULTIPROCESSOR) |
234 | extern vaddr_t cpu_spinup_trampoline; | | 234 | extern vaddr_t cpu_spinup_trampoline; |
235 | | | 235 | |
236 | extern char *mp_tramp_code; | | 236 | extern char *mp_tramp_code; |
237 | extern u_long mp_tramp_code_len; | | 237 | extern u_long mp_tramp_code_len; |
238 | extern u_long mp_tramp_tlb_slots; | | 238 | extern u_long mp_tramp_tlb_slots; |
239 | extern u_long mp_tramp_func; | | 239 | extern u_long mp_tramp_func; |
240 | extern u_long mp_tramp_ci; | | 240 | extern u_long mp_tramp_ci; |
241 | | | 241 | |
242 | void cpu_hatch(void); | | 242 | void cpu_hatch(void); |
243 | void cpu_boot_secondary_processors(void); | | 243 | void cpu_boot_secondary_processors(void); |
244 | | | 244 | |
245 | /* | | 245 | /* |
246 | * Call a function on other cpus: | | 246 | * Call a function on other cpus: |
247 | * multicast - send to everyone in the sparc64_cpuset_t | | 247 | * multicast - send to everyone in the sparc64_cpuset_t |
248 | * broadcast - send to to all cpus but ourselves | | 248 | * broadcast - send to to all cpus but ourselves |
249 | * send - send to just this cpu | | 249 | * send - send to just this cpu |
250 | * The called function do not follow the C ABI, so need to be coded in | | 250 | * The called function do not follow the C ABI, so need to be coded in |
251 | * assembler. | | 251 | * assembler. |
252 | */ | | 252 | */ |
253 | typedef void (* ipifunc_t)(void *, void *); | | 253 | typedef void (* ipifunc_t)(void *, void *); |
254 | | | 254 | |
255 | void sparc64_multicast_ipi(sparc64_cpuset_t, ipifunc_t, uint64_t, uint64_t); | | 255 | void sparc64_multicast_ipi(sparc64_cpuset_t, ipifunc_t, uint64_t, uint64_t); |
256 | void sparc64_broadcast_ipi(ipifunc_t, uint64_t, uint64_t); | | 256 | void sparc64_broadcast_ipi(ipifunc_t, uint64_t, uint64_t); |
257 | void sparc64_send_ipi(int, ipifunc_t, uint64_t, uint64_t); | | 257 | void sparc64_send_ipi(int, ipifunc_t, uint64_t, uint64_t); |
258 | | | 258 | |
259 | /* | | 259 | /* |
260 | * Call an arbitrary C function on another cpu (or all others but ourself) | | 260 | * Call an arbitrary C function on another cpu (or all others but ourself) |
261 | */ | | 261 | */ |
262 | typedef void (*ipi_c_call_func_t)(void*); | | 262 | typedef void (*ipi_c_call_func_t)(void*); |
263 | void sparc64_generic_xcall(struct cpu_info*, ipi_c_call_func_t, void*); | | 263 | void sparc64_generic_xcall(struct cpu_info*, ipi_c_call_func_t, void*); |
264 | | | 264 | |
265 | #endif | | 265 | #endif |
266 | | | 266 | |
| | | 267 | /* Provide %pc of a lwp */ |
| | | 268 | #define LWP_PC(l) ((l)->l_md.md_tf->tf_pc) |
| | | 269 | |
267 | /* | | 270 | /* |
268 | * Arguments to hardclock, softclock and gatherstats encapsulate the | | 271 | * Arguments to hardclock, softclock and gatherstats encapsulate the |
269 | * previous machine state in an opaque clockframe. The ipl is here | | 272 | * previous machine state in an opaque clockframe. The ipl is here |
270 | * as well for strayintr (see locore.s:interrupt and intr.c:strayintr). | | 273 | * as well for strayintr (see locore.s:interrupt and intr.c:strayintr). |
271 | * Note that CLKF_INTR is valid only if CLKF_USERMODE is false. | | 274 | * Note that CLKF_INTR is valid only if CLKF_USERMODE is false. |
272 | */ | | 275 | */ |
273 | struct clockframe { | | 276 | struct clockframe { |
274 | struct trapframe64 t; | | 277 | struct trapframe64 t; |
275 | }; | | 278 | }; |
276 | | | 279 | |
277 | #define CLKF_USERMODE(framep) (((framep)->t.tf_tstate & TSTATE_PRIV) == 0) | | 280 | #define CLKF_USERMODE(framep) (((framep)->t.tf_tstate & TSTATE_PRIV) == 0) |
278 | #define CLKF_PC(framep) ((framep)->t.tf_pc) | | 281 | #define CLKF_PC(framep) ((framep)->t.tf_pc) |
279 | /* Since some files in sys/kern do not know BIAS, I'm using 0x7ff here */ | | 282 | /* Since some files in sys/kern do not know BIAS, I'm using 0x7ff here */ |
280 | #define CLKF_INTR(framep) \ | | 283 | #define CLKF_INTR(framep) \ |
281 | ((!CLKF_USERMODE(framep))&& \ | | 284 | ((!CLKF_USERMODE(framep))&& \ |
282 | (((framep)->t.tf_out[6] & 1 ) ? \ | | 285 | (((framep)->t.tf_out[6] & 1 ) ? \ |
283 | (((vaddr_t)(framep)->t.tf_out[6] < \ | | 286 | (((vaddr_t)(framep)->t.tf_out[6] < \ |
284 | (vaddr_t)EINTSTACK-0x7ff) && \ | | 287 | (vaddr_t)EINTSTACK-0x7ff) && \ |
285 | ((vaddr_t)(framep)->t.tf_out[6] > \ | | 288 | ((vaddr_t)(framep)->t.tf_out[6] > \ |
286 | (vaddr_t)INTSTACK-0x7ff)) : \ | | 289 | (vaddr_t)INTSTACK-0x7ff)) : \ |
287 | (((vaddr_t)(framep)->t.tf_out[6] < \ | | 290 | (((vaddr_t)(framep)->t.tf_out[6] < \ |
288 | (vaddr_t)EINTSTACK) && \ | | 291 | (vaddr_t)EINTSTACK) && \ |
289 | ((vaddr_t)(framep)->t.tf_out[6] > \ | | 292 | ((vaddr_t)(framep)->t.tf_out[6] > \ |
290 | (vaddr_t)INTSTACK)))) | | 293 | (vaddr_t)INTSTACK)))) |
291 | | | 294 | |
292 | /* | | 295 | /* |
293 | * Give a profiling tick to the current process when the user profiling | | 296 | * Give a profiling tick to the current process when the user profiling |
294 | * buffer pages are invalid. On the sparc, request an ast to send us | | 297 | * buffer pages are invalid. On the sparc, request an ast to send us |
295 | * through trap(), marking the proc as needing a profiling tick. | | 298 | * through trap(), marking the proc as needing a profiling tick. |
296 | */ | | 299 | */ |
297 | #define cpu_need_proftick(l) ((l)->l_pflag |= LP_OWEUPC, want_ast = 1) | | 300 | #define cpu_need_proftick(l) ((l)->l_pflag |= LP_OWEUPC, want_ast = 1) |
298 | | | 301 | |
299 | /* | | 302 | /* |
300 | * Notify an LWP that it has a signal pending, process as soon as possible. | | 303 | * Notify an LWP that it has a signal pending, process as soon as possible. |
301 | */ | | 304 | */ |
302 | void cpu_signotify(struct lwp *); | | 305 | void cpu_signotify(struct lwp *); |
303 | | | 306 | |
304 | /* | | 307 | /* |
305 | * Interrupt handler chains. Interrupt handlers should return 0 for | | 308 | * Interrupt handler chains. Interrupt handlers should return 0 for |
306 | * ``not me'' or 1 (``I took care of it''). intr_establish() inserts a | | 309 | * ``not me'' or 1 (``I took care of it''). intr_establish() inserts a |
307 | * handler into the list. The handler is called with its (single) | | 310 | * handler into the list. The handler is called with its (single) |
308 | * argument, or with a pointer to a clockframe if ih_arg is NULL. | | 311 | * argument, or with a pointer to a clockframe if ih_arg is NULL. |
309 | */ | | 312 | */ |
310 | struct intrhand { | | 313 | struct intrhand { |
311 | int (*ih_fun)(void *); | | 314 | int (*ih_fun)(void *); |
312 | void *ih_arg; | | 315 | void *ih_arg; |
313 | /* if we have to take the biglock, we interpose a wrapper | | 316 | /* if we have to take the biglock, we interpose a wrapper |
314 | * and need to save the original function and arg */ | | 317 | * and need to save the original function and arg */ |
315 | int (*ih_realfun)(void *); | | 318 | int (*ih_realfun)(void *); |
316 | void *ih_realarg; | | 319 | void *ih_realarg; |
317 | short ih_number; /* interrupt number */ | | 320 | short ih_number; /* interrupt number */ |
318 | /* the H/W provides */ | | 321 | /* the H/W provides */ |
319 | char ih_pil; /* interrupt priority */ | | 322 | char ih_pil; /* interrupt priority */ |
320 | struct intrhand *ih_next; /* global list */ | | 323 | struct intrhand *ih_next; /* global list */ |
321 | struct intrhand *ih_pending; /* interrupt queued */ | | 324 | struct intrhand *ih_pending; /* interrupt queued */ |
322 | volatile uint64_t *ih_map; /* Interrupt map reg */ | | 325 | volatile uint64_t *ih_map; /* Interrupt map reg */ |
323 | volatile uint64_t *ih_clr; /* clear interrupt reg */ | | 326 | volatile uint64_t *ih_clr; /* clear interrupt reg */ |
324 | }; | | 327 | }; |
325 | extern struct intrhand *intrhand[]; | | 328 | extern struct intrhand *intrhand[]; |
326 | extern struct intrhand *intrlev[MAXINTNUM]; | | 329 | extern struct intrhand *intrlev[MAXINTNUM]; |
327 | | | 330 | |
328 | void intr_establish(int level, bool mpsafe, struct intrhand *); | | 331 | void intr_establish(int level, bool mpsafe, struct intrhand *); |
329 | void *sparc_softintr_establish(int, int (*)(void *), void *); | | 332 | void *sparc_softintr_establish(int, int (*)(void *), void *); |
330 | void sparc_softintr_schedule(void *); | | 333 | void sparc_softintr_schedule(void *); |
331 | void sparc_softintr_disestablish(void *); | | 334 | void sparc_softintr_disestablish(void *); |
332 | | | 335 | |
333 | /* disksubr.c */ | | 336 | /* disksubr.c */ |
334 | struct dkbad; | | 337 | struct dkbad; |
335 | int isbad(struct dkbad *bt, int, int, int); | | 338 | int isbad(struct dkbad *bt, int, int, int); |
336 | /* machdep.c */ | | 339 | /* machdep.c */ |
337 | void * reserve_dumppages(void *); | | 340 | void * reserve_dumppages(void *); |
338 | /* clock.c */ | | 341 | /* clock.c */ |
339 | struct timeval; | | 342 | struct timeval; |
340 | int tickintr(void *); /* level 10/14 (tick) interrupt code */ | | 343 | int tickintr(void *); /* level 10/14 (tick) interrupt code */ |
341 | int clockintr(void *); /* level 10 (clock) interrupt code */ | | 344 | int clockintr(void *); /* level 10 (clock) interrupt code */ |
342 | int statintr(void *); /* level 14 (statclock) interrupt code */ | | 345 | int statintr(void *); /* level 14 (statclock) interrupt code */ |
343 | int schedintr(void *); /* level 10 (schedclock) interrupt code */ | | 346 | int schedintr(void *); /* level 10 (schedclock) interrupt code */ |
344 | void tickintr_establish(int, int (*)(void *)); | | 347 | void tickintr_establish(int, int (*)(void *)); |
345 | /* locore.s */ | | 348 | /* locore.s */ |
346 | struct fpstate64; | | 349 | struct fpstate64; |
347 | void savefpstate(struct fpstate64 *); | | 350 | void savefpstate(struct fpstate64 *); |
348 | void loadfpstate(struct fpstate64 *); | | 351 | void loadfpstate(struct fpstate64 *); |
349 | void clearfpstate(void); | | 352 | void clearfpstate(void); |
350 | uint64_t probeget(paddr_t, int, int); | | 353 | uint64_t probeget(paddr_t, int, int); |
351 | int probeset(paddr_t, int, int, uint64_t); | | 354 | int probeset(paddr_t, int, int, uint64_t); |
352 | | | 355 | |
353 | #define write_all_windows() __asm volatile("flushw" : : ) | | 356 | #define write_all_windows() __asm volatile("flushw" : : ) |
354 | #define write_user_windows() __asm volatile("flushw" : : ) | | 357 | #define write_user_windows() __asm volatile("flushw" : : ) |
355 | | | 358 | |
356 | struct pcb; | | 359 | struct pcb; |
357 | void snapshot(struct pcb *); | | 360 | void snapshot(struct pcb *); |
358 | struct frame *getfp(void); | | 361 | struct frame *getfp(void); |
359 | void switchtoctx_us(int); | | 362 | void switchtoctx_us(int); |
360 | void switchtoctx_usiii(int); | | 363 | void switchtoctx_usiii(int); |
361 | void next_tick(long); | | 364 | void next_tick(long); |
362 | /* trap.c */ | | 365 | /* trap.c */ |
363 | void kill_user_windows(struct lwp *); | | 366 | void kill_user_windows(struct lwp *); |
364 | int rwindow_save(struct lwp *); | | 367 | int rwindow_save(struct lwp *); |
365 | /* cons.c */ | | 368 | /* cons.c */ |
366 | int cnrom(void); | | 369 | int cnrom(void); |
367 | /* zs.c */ | | 370 | /* zs.c */ |
368 | void zsconsole(struct tty *, int, int, void (**)(struct tty *, int)); | | 371 | void zsconsole(struct tty *, int, int, void (**)(struct tty *, int)); |
369 | /* fb.c */ | | 372 | /* fb.c */ |
370 | void fb_unblank(void); | | 373 | void fb_unblank(void); |
371 | /* kgdb_stub.c */ | | 374 | /* kgdb_stub.c */ |
372 | #ifdef KGDB | | 375 | #ifdef KGDB |
373 | void kgdb_attach(int (*)(void *), void (*)(void *, int), void *); | | 376 | void kgdb_attach(int (*)(void *), void (*)(void *, int), void *); |
374 | void kgdb_connect(int); | | 377 | void kgdb_connect(int); |
375 | void kgdb_panic(void); | | 378 | void kgdb_panic(void); |
376 | #endif | | 379 | #endif |
377 | /* emul.c */ | | 380 | /* emul.c */ |
378 | int fixalign(struct lwp *, struct trapframe64 *); | | 381 | int fixalign(struct lwp *, struct trapframe64 *); |
379 | int emulinstr(vaddr_t, struct trapframe64 *); | | 382 | int emulinstr(vaddr_t, struct trapframe64 *); |
380 | | | 383 | |
381 | #endif /* _KERNEL */ | | 384 | #endif /* _KERNEL */ |
382 | #endif /* _CPU_H_ */ | | 385 | #endif /* _CPU_H_ */ |