locore.h revision 1.79 1 1.79 martin /* $NetBSD: locore.h,v 1.79 2009/05/30 18:26:06 martin Exp $ */
2 1.1 jonathan
3 1.1 jonathan /*
4 1.1 jonathan * Copyright 1996 The Board of Trustees of The Leland Stanford
5 1.1 jonathan * Junior University. All Rights Reserved.
6 1.1 jonathan *
7 1.1 jonathan * Permission to use, copy, modify, and distribute this
8 1.1 jonathan * software and its documentation for any purpose and without
9 1.1 jonathan * fee is hereby granted, provided that the above copyright
10 1.1 jonathan * notice appear in all copies. Stanford University
11 1.1 jonathan * makes no representations about the suitability of this
12 1.1 jonathan * software for any purpose. It is provided "as is" without
13 1.1 jonathan * express or implied warranty.
14 1.1 jonathan */
15 1.1 jonathan
16 1.1 jonathan /*
17 1.68 wiz * Jump table for MIPS CPU locore functions that are implemented
18 1.1 jonathan * differently on different generations, or instruction-level
19 1.1 jonathan * archtecture (ISA) level, the Mips family.
20 1.1 jonathan *
21 1.33 soren * We currently provide support for MIPS I and MIPS III.
22 1.1 jonathan */
23 1.1 jonathan
24 1.1 jonathan #ifndef _MIPS_LOCORE_H
25 1.70 tsutsui #define _MIPS_LOCORE_H
26 1.2 jonathan
27 1.17 castor #ifndef _LKM
28 1.32 soren #include "opt_cputype.h"
29 1.17 castor #endif
30 1.16 castor
31 1.59 simonb #include <mips/cpuregs.h>
32 1.59 simonb
33 1.38 cgd struct tlb;
34 1.38 cgd
35 1.59 simonb uint32_t mips_cp0_cause_read(void);
36 1.59 simonb void mips_cp0_cause_write(uint32_t);
37 1.59 simonb uint32_t mips_cp0_status_read(void);
38 1.59 simonb void mips_cp0_status_write(uint32_t);
39 1.29 simonb
40 1.77 tsutsui int _splraise(int);
41 1.77 tsutsui int _spllower(int);
42 1.77 tsutsui int _splset(int);
43 1.77 tsutsui int _splget(void);
44 1.77 tsutsui void _splnone(void);
45 1.77 tsutsui void _setsoftintr(int);
46 1.77 tsutsui void _clrsoftintr(int);
47 1.77 tsutsui
48 1.59 simonb #ifdef MIPS1
49 1.54 simonb void mips1_SetPID(int);
50 1.38 cgd void mips1_TBIA(int);
51 1.38 cgd void mips1_TBIAP(int);
52 1.38 cgd void mips1_TBIS(vaddr_t);
53 1.38 cgd int mips1_TLBUpdate(u_int, u_int);
54 1.38 cgd void mips1_wbflush(void);
55 1.76 yamt void mips1_lwp_trampoline(void);
56 1.79 martin void mips1_setfunc_trampoline(void);
57 1.38 cgd void mips1_cpu_switch_resume(void);
58 1.38 cgd
59 1.58 thorpej uint32_t tx3900_cp0_config_read(void);
60 1.59 simonb #endif
61 1.38 cgd
62 1.59 simonb #if defined(MIPS3) || defined(MIPS4)
63 1.54 simonb void mips3_SetPID(int);
64 1.38 cgd void mips3_TBIA(int);
65 1.38 cgd void mips3_TBIAP(int);
66 1.38 cgd void mips3_TBIS(vaddr_t);
67 1.38 cgd int mips3_TLBUpdate(u_int, u_int);
68 1.38 cgd void mips3_TLBRead(int, struct tlb *);
69 1.71 tsutsui void mips3_TLBWriteIndexedVPS(int, struct tlb *);
70 1.38 cgd void mips3_wbflush(void);
71 1.76 yamt void mips3_lwp_trampoline(void);
72 1.79 martin void mips3_setfunc_trampoline(void);
73 1.38 cgd void mips3_cpu_switch_resume(void);
74 1.75 christos void mips3_pagezero(void *dst);
75 1.38 cgd
76 1.59 simonb #ifdef MIPS3_5900
77 1.59 simonb void mips5900_SetPID(int);
78 1.59 simonb void mips5900_TBIA(int);
79 1.59 simonb void mips5900_TBIAP(int);
80 1.59 simonb void mips5900_TBIS(vaddr_t);
81 1.59 simonb int mips5900_TLBUpdate(u_int, u_int);
82 1.59 simonb void mips5900_TLBRead(int, struct tlb *);
83 1.71 tsutsui void mips5900_TLBWriteIndexedVPS(int, struct tlb *);
84 1.59 simonb void mips5900_wbflush(void);
85 1.76 yamt void mips5900_lwp_trampoline(void);
86 1.79 martin void mips5900_setfunc_trampoline(void);
87 1.59 simonb void mips5900_cpu_switch_resume(void);
88 1.75 christos void mips5900_pagezero(void *dst);
89 1.59 simonb #endif
90 1.59 simonb #endif
91 1.49 cgd
92 1.59 simonb #ifdef MIPS32
93 1.59 simonb void mips32_SetPID(int);
94 1.59 simonb void mips32_TBIA(int);
95 1.59 simonb void mips32_TBIAP(int);
96 1.59 simonb void mips32_TBIS(vaddr_t);
97 1.59 simonb int mips32_TLBUpdate(u_int, u_int);
98 1.59 simonb void mips32_TLBRead(int, struct tlb *);
99 1.71 tsutsui void mips32_TLBWriteIndexedVPS(int, struct tlb *);
100 1.59 simonb void mips32_wbflush(void);
101 1.76 yamt void mips32_lwp_trampoline(void);
102 1.79 martin void mips32_setfunc_trampoline(void);
103 1.59 simonb void mips32_cpu_switch_resume(void);
104 1.59 simonb #endif
105 1.59 simonb
106 1.59 simonb #ifdef MIPS64
107 1.59 simonb void mips64_SetPID(int);
108 1.59 simonb void mips64_TBIA(int);
109 1.59 simonb void mips64_TBIAP(int);
110 1.59 simonb void mips64_TBIS(vaddr_t);
111 1.59 simonb int mips64_TLBUpdate(u_int, u_int);
112 1.59 simonb void mips64_TLBRead(int, struct tlb *);
113 1.71 tsutsui void mips64_TLBWriteIndexedVPS(int, struct tlb *);
114 1.59 simonb void mips64_wbflush(void);
115 1.76 yamt void mips64_lwp_trampoline(void);
116 1.79 martin void mips64_setfunc_trampoline(void);
117 1.59 simonb void mips64_cpu_switch_resume(void);
118 1.75 christos void mips64_pagezero(void *dst);
119 1.59 simonb #endif
120 1.49 cgd
121 1.63 simonb #if defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64)
122 1.59 simonb uint32_t mips3_cp0_compare_read(void);
123 1.59 simonb void mips3_cp0_compare_write(uint32_t);
124 1.49 cgd
125 1.59 simonb uint32_t mips3_cp0_config_read(void);
126 1.59 simonb void mips3_cp0_config_write(uint32_t);
127 1.63 simonb #if defined(MIPS32) || defined(MIPS64)
128 1.59 simonb uint32_t mipsNN_cp0_config1_read(void);
129 1.59 simonb void mipsNN_cp0_config1_write(uint32_t);
130 1.63 simonb uint32_t mipsNN_cp0_config2_read(void);
131 1.63 simonb uint32_t mipsNN_cp0_config3_read(void);
132 1.63 simonb #endif
133 1.59 simonb
134 1.59 simonb uint32_t mips3_cp0_count_read(void);
135 1.59 simonb void mips3_cp0_count_write(uint32_t);
136 1.59 simonb
137 1.59 simonb uint32_t mips3_cp0_wired_read(void);
138 1.59 simonb void mips3_cp0_wired_write(uint32_t);
139 1.69 tsutsui void mips3_cp0_pg_mask_write(uint32_t);
140 1.59 simonb
141 1.59 simonb uint64_t mips3_ld(uint64_t *);
142 1.59 simonb void mips3_sd(uint64_t *, uint64_t);
143 1.63 simonb #endif /* MIPS3 || MIPS4 || MIPS32 || MIPS64 */
144 1.59 simonb
145 1.63 simonb #if defined(MIPS3) || defined(MIPS4) || defined(MIPS64)
146 1.74 perry static __inline uint32_t mips3_lw_a64(uint64_t addr)
147 1.59 simonb __attribute__((__unused__));
148 1.74 perry static __inline void mips3_sw_a64(uint64_t addr, uint32_t val)
149 1.59 simonb __attribute__ ((__unused__));
150 1.59 simonb
151 1.74 perry static __inline uint32_t
152 1.59 simonb mips3_lw_a64(uint64_t addr)
153 1.59 simonb {
154 1.59 simonb uint32_t addrlo, addrhi;
155 1.59 simonb uint32_t rv;
156 1.59 simonb uint32_t sr;
157 1.59 simonb
158 1.59 simonb sr = mips_cp0_status_read();
159 1.59 simonb mips_cp0_status_write(sr | MIPS3_SR_KX);
160 1.59 simonb
161 1.59 simonb addrlo = addr & 0xffffffff;
162 1.59 simonb addrhi = addr >> 32;
163 1.73 perry __asm volatile (" \n\
164 1.59 simonb .set push \n\
165 1.59 simonb .set mips3 \n\
166 1.59 simonb .set noreorder \n\
167 1.59 simonb .set noat \n\
168 1.59 simonb dsll32 $3, %1, 0 \n\
169 1.59 simonb dsll32 $1, %2, 0 \n\
170 1.59 simonb dsrl32 $3, $3, 0 \n\
171 1.59 simonb or $1, $1, $3 \n\
172 1.59 simonb lw %0, 0($1) \n\
173 1.59 simonb .set pop \n\
174 1.59 simonb " : "=r"(rv) : "r"(addrlo), "r"(addrhi) : "$1", "$3" );
175 1.59 simonb
176 1.59 simonb mips_cp0_status_write(sr);
177 1.59 simonb
178 1.59 simonb return (rv);
179 1.59 simonb }
180 1.59 simonb
181 1.74 perry static __inline void
182 1.59 simonb mips3_sw_a64(uint64_t addr, uint32_t val)
183 1.59 simonb {
184 1.59 simonb uint32_t addrlo, addrhi;
185 1.59 simonb uint32_t sr;
186 1.59 simonb
187 1.59 simonb sr = mips_cp0_status_read();
188 1.59 simonb mips_cp0_status_write(sr | MIPS3_SR_KX);
189 1.59 simonb
190 1.59 simonb addrlo = addr & 0xffffffff;
191 1.59 simonb addrhi = addr >> 32;
192 1.73 perry __asm volatile (" \n\
193 1.59 simonb .set push \n\
194 1.59 simonb .set mips3 \n\
195 1.59 simonb .set noreorder \n\
196 1.59 simonb .set noat \n\
197 1.59 simonb dsll32 $3, %1, 0 \n\
198 1.59 simonb dsll32 $1, %2, 0 \n\
199 1.59 simonb dsrl32 $3, $3, 0 \n\
200 1.59 simonb or $1, $1, $3 \n\
201 1.59 simonb sw %0, 0($1) \n\
202 1.59 simonb .set pop \n\
203 1.59 simonb " : : "r"(val), "r"(addrlo), "r"(addrhi) : "$1", "$3" );
204 1.44 cgd
205 1.59 simonb mips_cp0_status_write(sr);
206 1.59 simonb }
207 1.63 simonb #endif /* MIPS3 || MIPS4 || MIPS64 */
208 1.7 jonathan
209 1.1 jonathan /*
210 1.58 thorpej * A vector with an entry for each mips-ISA-level dependent
211 1.1 jonathan * locore function, and macros which jump through it.
212 1.58 thorpej *
213 1.1 jonathan * XXX the macro names are chosen to be compatible with the old
214 1.58 thorpej * XXX Sprite coding-convention names used in 4.4bsd/pmax.
215 1.1 jonathan */
216 1.1 jonathan typedef struct {
217 1.38 cgd void (*setTLBpid)(int pid);
218 1.38 cgd void (*TBIAP)(int);
219 1.38 cgd void (*TBIS)(vaddr_t);
220 1.38 cgd int (*tlbUpdate)(u_int highreg, u_int lowreg);
221 1.38 cgd void (*wbflush)(void);
222 1.1 jonathan } mips_locore_jumpvec_t;
223 1.13 jonathan
224 1.38 cgd void mips_set_wbflush(void (*)(void));
225 1.62 simonb void mips_wait_idle(void);
226 1.1 jonathan
227 1.38 cgd void stacktrace(void);
228 1.38 cgd void logstacktrace(void);
229 1.1 jonathan
230 1.1 jonathan /*
231 1.1 jonathan * The "active" locore-fuction vector, and
232 1.1 jonathan */
233 1.1 jonathan extern mips_locore_jumpvec_t mips_locore_jumpvec;
234 1.31 nisimura extern long *mips_locoresw[];
235 1.1 jonathan
236 1.59 simonb #if defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64)
237 1.11 jonathan #define MachSetPID mips1_SetPID
238 1.30 nisimura #define MIPS_TBIAP() mips1_TBIAP(mips_num_tlb_entries)
239 1.30 nisimura #define MIPS_TBIS mips1_TBIS
240 1.11 jonathan #define MachTLBUpdate mips1_TLBUpdate
241 1.22 nisimura #define wbflush() mips1_wbflush()
242 1.76 yamt #define lwp_trampoline mips1_lwp_trampoline
243 1.79 martin #define setfunc_trampoline mips1_setfunc_trampoline
244 1.60 uch #elif !defined(MIPS1) && defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && !defined(MIPS3_5900)
245 1.59 simonb #define MachSetPID mips3_SetPID
246 1.59 simonb #define MIPS_TBIAP() mips3_TBIAP(mips_num_tlb_entries)
247 1.59 simonb #define MIPS_TBIS mips3_TBIS
248 1.59 simonb #define MachTLBUpdate mips3_TLBUpdate
249 1.71 tsutsui #define MachTLBWriteIndexedVPS mips3_TLBWriteIndexedVPS
250 1.76 yamt #define lwp_trampoline mips3_lwp_trampoline
251 1.79 martin #define setfunc_trampoline mips3_setfunc_trampoline
252 1.59 simonb #define wbflush() mips3_wbflush()
253 1.59 simonb #elif !defined(MIPS1) && !defined(MIPS3) && defined(MIPS32) && !defined(MIPS64)
254 1.70 tsutsui #define MachSetPID mips32_SetPID
255 1.70 tsutsui #define MIPS_TBIAP() mips32_TBIAP(mips_num_tlb_entries)
256 1.70 tsutsui #define MIPS_TBIS mips32_TBIS
257 1.70 tsutsui #define MachTLBUpdate mips32_TLBUpdate
258 1.71 tsutsui #define MachTLBWriteIndexedVPS mips32_TLBWriteIndexedVPS
259 1.76 yamt #define lwp_trampoline mips32_lwp_trampoline
260 1.79 martin #define setfunc_trampoline mips32_setfunc_trampoline
261 1.59 simonb #define wbflush() mips32_wbflush()
262 1.59 simonb #elif !defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && defined(MIPS64)
263 1.59 simonb /* all common with mips3 */
264 1.59 simonb #define MachSetPID mips64_SetPID
265 1.59 simonb #define MIPS_TBIAP() mips64_TBIAP(mips_num_tlb_entries)
266 1.59 simonb #define MIPS_TBIS mips64_TBIS
267 1.59 simonb #define MachTLBUpdate mips64_TLBUpdate
268 1.71 tsutsui #define MachTLBWriteIndexedVPS mips64_TLBWriteIndexedVPS
269 1.76 yamt #define lwp_trampoline mips64_lwp_trampoline
270 1.79 martin #define setfunc_trampoline mips64_setfunc_trampoline
271 1.59 simonb #define wbflush() mips64_wbflush()
272 1.60 uch #elif !defined(MIPS1) && defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && defined(MIPS3_5900)
273 1.60 uch #define MachSetPID mips5900_SetPID
274 1.60 uch #define MIPS_TBIAP() mips5900_TBIAP(mips_num_tlb_entries)
275 1.60 uch #define MIPS_TBIS mips5900_TBIS
276 1.60 uch #define MachTLBUpdate mips5900_TLBUpdate
277 1.71 tsutsui #define MachTLBWriteIndexedVPS mips5900_TLBWriteIndexedVPS
278 1.76 yamt #define lwp_trampoline mips5900_lwp_trampoline
279 1.79 martin #define setfunc_trampoline mips5900_setfunc_trampoline
280 1.60 uch #define wbflush() mips5900_wbflush()
281 1.59 simonb #else
282 1.1 jonathan #define MachSetPID (*(mips_locore_jumpvec.setTLBpid))
283 1.31 nisimura #define MIPS_TBIAP() (*(mips_locore_jumpvec.TBIAP))(mips_num_tlb_entries)
284 1.31 nisimura #define MIPS_TBIS (*(mips_locore_jumpvec.TBIS))
285 1.1 jonathan #define MachTLBUpdate (*(mips_locore_jumpvec.tlbUpdate))
286 1.22 nisimura #define wbflush() (*(mips_locore_jumpvec.wbflush))()
287 1.76 yamt #define lwp_trampoline (mips_locoresw[1])
288 1.79 martin #define setfunc_trampoline (mips_locoresw[3])
289 1.11 jonathan #endif
290 1.31 nisimura
291 1.31 nisimura #define CPU_IDLE (mips_locoresw[2])
292 1.11 jonathan
293 1.16 castor /* cpu_switch_resume is called inside locore.S */
294 1.7 jonathan
295 1.7 jonathan /*
296 1.7 jonathan * CPU identification, from PRID register.
297 1.7 jonathan */
298 1.40 cgd typedef int mips_prid_t;
299 1.40 cgd
300 1.70 tsutsui #define MIPS_PRID_REV(x) (((x) >> 0) & 0x00ff)
301 1.70 tsutsui #define MIPS_PRID_IMPL(x) (((x) >> 8) & 0x00ff)
302 1.45 cgd
303 1.59 simonb /* pre-MIPS32/64 */
304 1.70 tsutsui #define MIPS_PRID_RSVD(x) (((x) >> 16) & 0xffff)
305 1.70 tsutsui #define MIPS_PRID_REV_MIN(x) ((MIPS_PRID_REV(x) >> 0) & 0x0f)
306 1.70 tsutsui #define MIPS_PRID_REV_MAJ(x) ((MIPS_PRID_REV(x) >> 4) & 0x0f)
307 1.45 cgd
308 1.59 simonb /* MIPS32/64 */
309 1.70 tsutsui #define MIPS_PRID_CID(x) (((x) >> 16) & 0x00ff) /* Company ID */
310 1.70 tsutsui #define MIPS_PRID_CID_PREHISTORIC 0x00 /* Not MIPS32/64 */
311 1.70 tsutsui #define MIPS_PRID_CID_MTI 0x01 /* MIPS Technologies, Inc. */
312 1.70 tsutsui #define MIPS_PRID_CID_BROADCOM 0x02 /* Broadcom */
313 1.70 tsutsui #define MIPS_PRID_CID_ALCHEMY 0x03 /* Alchemy Semiconductor */
314 1.70 tsutsui #define MIPS_PRID_CID_SIBYTE 0x04 /* SiByte */
315 1.70 tsutsui #define MIPS_PRID_CID_SANDCRAFT 0x05 /* SandCraft */
316 1.70 tsutsui #define MIPS_PRID_CID_PHILIPS 0x06 /* Philips */
317 1.70 tsutsui #define MIPS_PRID_CID_TOSHIBA 0x07 /* Toshiba */
318 1.70 tsutsui #define MIPS_PRID_CID_LSI 0x08 /* LSI */
319 1.67 simonb /* 0x09 unannounced */
320 1.67 simonb /* 0x0a unannounced */
321 1.70 tsutsui #define MIPS_PRID_CID_LEXRA 0x0b /* Lexra */
322 1.70 tsutsui #define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */
323 1.6 jonathan
324 1.6 jonathan #ifdef _KERNEL
325 1.6 jonathan /*
326 1.6 jonathan * Global variables used to communicate CPU type, and parameters
327 1.6 jonathan * such as cache size, from locore to higher-level code (e.g., pmap).
328 1.6 jonathan */
329 1.40 cgd
330 1.40 cgd extern mips_prid_t cpu_id;
331 1.40 cgd extern mips_prid_t fpu_id;
332 1.14 jonathan extern int mips_num_tlb_entries;
333 1.52 jeffs
334 1.75 christos void mips_pagecopy(void *dst, void *src);
335 1.75 christos void mips_pagezero(void *dst);
336 1.19 jonathan
337 1.59 simonb #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
338 1.59 simonb void mips_machdep_cache_config(void);
339 1.59 simonb #endif
340 1.59 simonb
341 1.19 jonathan /*
342 1.20 simonb * trapframe argument passed to trap()
343 1.19 jonathan */
344 1.64 thorpej
345 1.70 tsutsui #define TF_AST 0
346 1.70 tsutsui #define TF_V0 1
347 1.70 tsutsui #define TF_V1 2
348 1.70 tsutsui #define TF_A0 3
349 1.70 tsutsui #define TF_A1 4
350 1.70 tsutsui #define TF_A2 5
351 1.70 tsutsui #define TF_A3 6
352 1.70 tsutsui #define TF_T0 7
353 1.70 tsutsui #define TF_T1 8
354 1.70 tsutsui #define TF_T2 9
355 1.70 tsutsui #define TF_T3 10
356 1.64 thorpej
357 1.64 thorpej #if defined(__mips_n32) || defined(__mips_n64)
358 1.70 tsutsui #define TF_A4 11
359 1.70 tsutsui #define TF_A5 12
360 1.70 tsutsui #define TF_A6 13
361 1.70 tsutsui #define TF_A7 14
362 1.64 thorpej #else
363 1.70 tsutsui #define TF_T4 11
364 1.70 tsutsui #define TF_T5 12
365 1.70 tsutsui #define TF_T6 13
366 1.70 tsutsui #define TF_T7 14
367 1.64 thorpej #endif /* __mips_n32 || __mips_n64 */
368 1.64 thorpej
369 1.70 tsutsui #define TF_TA0 11
370 1.70 tsutsui #define TF_TA1 12
371 1.70 tsutsui #define TF_TA2 13
372 1.70 tsutsui #define TF_TA3 14
373 1.70 tsutsui
374 1.70 tsutsui #define TF_T8 15
375 1.70 tsutsui #define TF_T9 16
376 1.70 tsutsui
377 1.70 tsutsui #define TF_RA 17
378 1.70 tsutsui #define TF_SR 18
379 1.70 tsutsui #define TF_MULLO 19
380 1.70 tsutsui #define TF_MULHI 20
381 1.70 tsutsui #define TF_EPC 21 /* may be changed by trap() call */
382 1.65 thorpej
383 1.70 tsutsui #define TF_NREGS 22
384 1.64 thorpej
385 1.19 jonathan struct trapframe {
386 1.64 thorpej mips_reg_t tf_regs[TF_NREGS];
387 1.57 uch u_int32_t tf_ppl; /* previous priority level */
388 1.57 uch int32_t tf_pad; /* for 8 byte aligned */
389 1.19 jonathan };
390 1.19 jonathan
391 1.19 jonathan /*
392 1.19 jonathan * Stack frame for kernel traps. four args passed in registers.
393 1.19 jonathan * A trapframe is pointed to by the 5th arg, and a dummy sixth argument
394 1.19 jonathan * is used to avoid alignment problems
395 1.19 jonathan */
396 1.19 jonathan
397 1.19 jonathan struct kernframe {
398 1.19 jonathan register_t cf_args[4 + 1];
399 1.19 jonathan register_t cf_pad; /* (for 8 word alignment) */
400 1.19 jonathan register_t cf_sp;
401 1.19 jonathan register_t cf_ra;
402 1.19 jonathan struct trapframe cf_frame;
403 1.19 jonathan };
404 1.61 simonb #endif /* _KERNEL */
405 1.1 jonathan #endif /* _MIPS_LOCORE_H */
406