locore.h revision 1.58.2.3 1 1.58.2.3 nathanw /* $NetBSD: locore.h,v 1.58.2.3 2002/06/20 03:39:46 nathanw Exp $ */
2 1.58.2.2 nathanw
3 1.58.2.2 nathanw /*
4 1.58.2.2 nathanw * Copyright 1996 The Board of Trustees of The Leland Stanford
5 1.58.2.2 nathanw * Junior University. All Rights Reserved.
6 1.58.2.2 nathanw *
7 1.58.2.2 nathanw * Permission to use, copy, modify, and distribute this
8 1.58.2.2 nathanw * software and its documentation for any purpose and without
9 1.58.2.2 nathanw * fee is hereby granted, provided that the above copyright
10 1.58.2.2 nathanw * notice appear in all copies. Stanford University
11 1.58.2.2 nathanw * makes no representations about the suitability of this
12 1.58.2.2 nathanw * software for any purpose. It is provided "as is" without
13 1.58.2.2 nathanw * express or implied warranty.
14 1.58.2.2 nathanw */
15 1.58.2.2 nathanw
16 1.58.2.2 nathanw /*
17 1.58.2.2 nathanw * Jump table for MIPS cpu locore functions that are implemented
18 1.58.2.2 nathanw * differently on different generations, or instruction-level
19 1.58.2.2 nathanw * archtecture (ISA) level, the Mips family.
20 1.58.2.2 nathanw *
21 1.58.2.2 nathanw * We currently provide support for MIPS I and MIPS III.
22 1.58.2.2 nathanw */
23 1.58.2.2 nathanw
24 1.58.2.2 nathanw #ifndef _MIPS_LOCORE_H
25 1.58.2.2 nathanw #define _MIPS_LOCORE_H
26 1.58.2.2 nathanw
27 1.58.2.2 nathanw #ifndef _LKM
28 1.58.2.2 nathanw #include "opt_cputype.h"
29 1.58.2.2 nathanw #include "opt_mips_cache.h"
30 1.58.2.2 nathanw #endif
31 1.58.2.2 nathanw
32 1.58.2.2 nathanw #include <mips/cpuregs.h>
33 1.58.2.2 nathanw
34 1.58.2.2 nathanw struct tlb;
35 1.58.2.2 nathanw
36 1.58.2.2 nathanw uint32_t mips_cp0_cause_read(void);
37 1.58.2.2 nathanw void mips_cp0_cause_write(uint32_t);
38 1.58.2.2 nathanw uint32_t mips_cp0_status_read(void);
39 1.58.2.2 nathanw void mips_cp0_status_write(uint32_t);
40 1.58.2.2 nathanw
41 1.58.2.2 nathanw #ifdef MIPS1
42 1.58.2.2 nathanw void mips1_SetPID(int);
43 1.58.2.2 nathanw void mips1_TBIA(int);
44 1.58.2.2 nathanw void mips1_TBIAP(int);
45 1.58.2.2 nathanw void mips1_TBIS(vaddr_t);
46 1.58.2.2 nathanw int mips1_TLBUpdate(u_int, u_int);
47 1.58.2.2 nathanw void mips1_wbflush(void);
48 1.58.2.2 nathanw void mips1_proc_trampoline(void);
49 1.58.2.2 nathanw void mips1_cpu_switch_resume(void);
50 1.58.2.2 nathanw
51 1.58.2.2 nathanw uint32_t tx3900_cp0_config_read(void);
52 1.58.2.2 nathanw #endif
53 1.58.2.2 nathanw
54 1.58.2.2 nathanw #if defined(MIPS3) || defined(MIPS4)
55 1.58.2.2 nathanw void mips3_SetPID(int);
56 1.58.2.2 nathanw void mips3_TBIA(int);
57 1.58.2.2 nathanw void mips3_TBIAP(int);
58 1.58.2.2 nathanw void mips3_TBIS(vaddr_t);
59 1.58.2.2 nathanw int mips3_TLBUpdate(u_int, u_int);
60 1.58.2.2 nathanw void mips3_TLBRead(int, struct tlb *);
61 1.58.2.2 nathanw void mips3_wbflush(void);
62 1.58.2.2 nathanw void mips3_proc_trampoline(void);
63 1.58.2.2 nathanw void mips3_cpu_switch_resume(void);
64 1.58.2.3 nathanw void mips3_pagezero(caddr_t dst);
65 1.58.2.2 nathanw
66 1.58.2.2 nathanw #ifdef MIPS3_5900
67 1.58.2.2 nathanw void mips5900_SetPID(int);
68 1.58.2.2 nathanw void mips5900_TBIA(int);
69 1.58.2.2 nathanw void mips5900_TBIAP(int);
70 1.58.2.2 nathanw void mips5900_TBIS(vaddr_t);
71 1.58.2.2 nathanw int mips5900_TLBUpdate(u_int, u_int);
72 1.58.2.2 nathanw void mips5900_TLBRead(int, struct tlb *);
73 1.58.2.2 nathanw void mips5900_wbflush(void);
74 1.58.2.2 nathanw void mips5900_proc_trampoline(void);
75 1.58.2.2 nathanw void mips5900_cpu_switch_resume(void);
76 1.58.2.3 nathanw void mips5900_pagezero(caddr_t dst);
77 1.58.2.2 nathanw #endif
78 1.58.2.2 nathanw #endif
79 1.58.2.2 nathanw
80 1.58.2.2 nathanw #ifdef MIPS32
81 1.58.2.2 nathanw void mips32_SetPID(int);
82 1.58.2.2 nathanw void mips32_TBIA(int);
83 1.58.2.2 nathanw void mips32_TBIAP(int);
84 1.58.2.2 nathanw void mips32_TBIS(vaddr_t);
85 1.58.2.2 nathanw int mips32_TLBUpdate(u_int, u_int);
86 1.58.2.2 nathanw void mips32_TLBRead(int, struct tlb *);
87 1.58.2.2 nathanw void mips32_wbflush(void);
88 1.58.2.2 nathanw void mips32_proc_trampoline(void);
89 1.58.2.2 nathanw void mips32_cpu_switch_resume(void);
90 1.58.2.2 nathanw #endif
91 1.58.2.2 nathanw
92 1.58.2.2 nathanw #ifdef MIPS64
93 1.58.2.2 nathanw void mips64_SetPID(int);
94 1.58.2.2 nathanw void mips64_TBIA(int);
95 1.58.2.2 nathanw void mips64_TBIAP(int);
96 1.58.2.2 nathanw void mips64_TBIS(vaddr_t);
97 1.58.2.2 nathanw int mips64_TLBUpdate(u_int, u_int);
98 1.58.2.2 nathanw void mips64_TLBRead(int, struct tlb *);
99 1.58.2.2 nathanw void mips64_wbflush(void);
100 1.58.2.2 nathanw void mips64_proc_trampoline(void);
101 1.58.2.2 nathanw void mips64_cpu_switch_resume(void);
102 1.58.2.3 nathanw void mips64_pagezero(caddr_t dst);
103 1.58.2.2 nathanw #endif
104 1.58.2.2 nathanw
105 1.58.2.3 nathanw #if defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64)
106 1.58.2.2 nathanw uint32_t mips3_cp0_compare_read(void);
107 1.58.2.2 nathanw void mips3_cp0_compare_write(uint32_t);
108 1.58.2.2 nathanw
109 1.58.2.2 nathanw uint32_t mips3_cp0_config_read(void);
110 1.58.2.2 nathanw void mips3_cp0_config_write(uint32_t);
111 1.58.2.3 nathanw #if defined(MIPS32) || defined(MIPS64)
112 1.58.2.2 nathanw uint32_t mipsNN_cp0_config1_read(void);
113 1.58.2.2 nathanw void mipsNN_cp0_config1_write(uint32_t);
114 1.58.2.3 nathanw uint32_t mipsNN_cp0_config2_read(void);
115 1.58.2.3 nathanw uint32_t mipsNN_cp0_config3_read(void);
116 1.58.2.3 nathanw #endif
117 1.58.2.2 nathanw
118 1.58.2.2 nathanw uint32_t mips3_cp0_count_read(void);
119 1.58.2.2 nathanw void mips3_cp0_count_write(uint32_t);
120 1.58.2.2 nathanw
121 1.58.2.2 nathanw uint32_t mips3_cp0_wired_read(void);
122 1.58.2.2 nathanw void mips3_cp0_wired_write(uint32_t);
123 1.58.2.2 nathanw
124 1.58.2.2 nathanw uint64_t mips3_ld(uint64_t *);
125 1.58.2.2 nathanw void mips3_sd(uint64_t *, uint64_t);
126 1.58.2.3 nathanw #endif /* MIPS3 || MIPS4 || MIPS32 || MIPS64 */
127 1.58.2.2 nathanw
128 1.58.2.3 nathanw #if defined(MIPS3) || defined(MIPS4) || defined(MIPS64)
129 1.58.2.2 nathanw static inline uint32_t mips3_lw_a64(uint64_t addr)
130 1.58.2.2 nathanw __attribute__((__unused__));
131 1.58.2.2 nathanw static inline void mips3_sw_a64(uint64_t addr, uint32_t val)
132 1.58.2.2 nathanw __attribute__ ((__unused__));
133 1.58.2.2 nathanw
134 1.58.2.2 nathanw static inline uint32_t
135 1.58.2.2 nathanw mips3_lw_a64(uint64_t addr)
136 1.58.2.2 nathanw {
137 1.58.2.2 nathanw uint32_t addrlo, addrhi;
138 1.58.2.2 nathanw uint32_t rv;
139 1.58.2.2 nathanw uint32_t sr;
140 1.58.2.2 nathanw
141 1.58.2.2 nathanw sr = mips_cp0_status_read();
142 1.58.2.2 nathanw mips_cp0_status_write(sr | MIPS3_SR_KX);
143 1.58.2.2 nathanw
144 1.58.2.2 nathanw addrlo = addr & 0xffffffff;
145 1.58.2.2 nathanw addrhi = addr >> 32;
146 1.58.2.2 nathanw __asm__ __volatile__ (" \n\
147 1.58.2.2 nathanw .set push \n\
148 1.58.2.2 nathanw .set mips3 \n\
149 1.58.2.2 nathanw .set noreorder \n\
150 1.58.2.2 nathanw .set noat \n\
151 1.58.2.2 nathanw dsll32 $3, %1, 0 \n\
152 1.58.2.2 nathanw dsll32 $1, %2, 0 \n\
153 1.58.2.2 nathanw dsrl32 $3, $3, 0 \n\
154 1.58.2.2 nathanw or $1, $1, $3 \n\
155 1.58.2.2 nathanw lw %0, 0($1) \n\
156 1.58.2.2 nathanw .set pop \n\
157 1.58.2.2 nathanw " : "=r"(rv) : "r"(addrlo), "r"(addrhi) : "$1", "$3" );
158 1.58.2.2 nathanw
159 1.58.2.2 nathanw mips_cp0_status_write(sr);
160 1.58.2.2 nathanw
161 1.58.2.2 nathanw return (rv);
162 1.58.2.2 nathanw }
163 1.58.2.2 nathanw
164 1.58.2.2 nathanw static inline void
165 1.58.2.2 nathanw mips3_sw_a64(uint64_t addr, uint32_t val)
166 1.58.2.2 nathanw {
167 1.58.2.2 nathanw uint32_t addrlo, addrhi;
168 1.58.2.2 nathanw uint32_t sr;
169 1.58.2.2 nathanw
170 1.58.2.2 nathanw sr = mips_cp0_status_read();
171 1.58.2.2 nathanw mips_cp0_status_write(sr | MIPS3_SR_KX);
172 1.58.2.2 nathanw
173 1.58.2.2 nathanw addrlo = addr & 0xffffffff;
174 1.58.2.2 nathanw addrhi = addr >> 32;
175 1.58.2.2 nathanw __asm__ __volatile__ (" \n\
176 1.58.2.2 nathanw .set push \n\
177 1.58.2.2 nathanw .set mips3 \n\
178 1.58.2.2 nathanw .set noreorder \n\
179 1.58.2.2 nathanw .set noat \n\
180 1.58.2.2 nathanw dsll32 $3, %1, 0 \n\
181 1.58.2.2 nathanw dsll32 $1, %2, 0 \n\
182 1.58.2.2 nathanw dsrl32 $3, $3, 0 \n\
183 1.58.2.2 nathanw or $1, $1, $3 \n\
184 1.58.2.2 nathanw sw %0, 0($1) \n\
185 1.58.2.2 nathanw .set pop \n\
186 1.58.2.2 nathanw " : : "r"(val), "r"(addrlo), "r"(addrhi) : "$1", "$3" );
187 1.58.2.2 nathanw
188 1.58.2.2 nathanw mips_cp0_status_write(sr);
189 1.58.2.2 nathanw }
190 1.58.2.3 nathanw #endif /* MIPS3 || MIPS4 || MIPS64 */
191 1.58.2.2 nathanw
192 1.58.2.2 nathanw /*
193 1.58.2.2 nathanw * A vector with an entry for each mips-ISA-level dependent
194 1.58.2.2 nathanw * locore function, and macros which jump through it.
195 1.58.2.2 nathanw *
196 1.58.2.2 nathanw * XXX the macro names are chosen to be compatible with the old
197 1.58.2.2 nathanw * XXX Sprite coding-convention names used in 4.4bsd/pmax.
198 1.58.2.2 nathanw */
199 1.58.2.2 nathanw typedef struct {
200 1.58.2.2 nathanw void (*setTLBpid)(int pid);
201 1.58.2.2 nathanw void (*TBIAP)(int);
202 1.58.2.2 nathanw void (*TBIS)(vaddr_t);
203 1.58.2.2 nathanw int (*tlbUpdate)(u_int highreg, u_int lowreg);
204 1.58.2.2 nathanw void (*wbflush)(void);
205 1.58.2.2 nathanw } mips_locore_jumpvec_t;
206 1.58.2.2 nathanw
207 1.58.2.2 nathanw void mips_set_wbflush(void (*)(void));
208 1.58.2.3 nathanw void mips_wait_idle(void);
209 1.58.2.2 nathanw
210 1.58.2.2 nathanw void stacktrace(void);
211 1.58.2.2 nathanw void logstacktrace(void);
212 1.58.2.2 nathanw
213 1.58.2.2 nathanw /*
214 1.58.2.2 nathanw * The "active" locore-fuction vector, and
215 1.58.2.2 nathanw */
216 1.58.2.2 nathanw extern mips_locore_jumpvec_t mips_locore_jumpvec;
217 1.58.2.2 nathanw extern long *mips_locoresw[];
218 1.58.2.2 nathanw
219 1.58.2.2 nathanw #if defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64)
220 1.58.2.2 nathanw #define MachSetPID mips1_SetPID
221 1.58.2.2 nathanw #define MIPS_TBIAP() mips1_TBIAP(mips_num_tlb_entries)
222 1.58.2.2 nathanw #define MIPS_TBIS mips1_TBIS
223 1.58.2.2 nathanw #define MachTLBUpdate mips1_TLBUpdate
224 1.58.2.2 nathanw #define wbflush() mips1_wbflush()
225 1.58.2.2 nathanw #define proc_trampoline mips1_proc_trampoline
226 1.58.2.2 nathanw #elif !defined(MIPS1) && defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && !defined(MIPS3_5900)
227 1.58.2.2 nathanw #define MachSetPID mips3_SetPID
228 1.58.2.2 nathanw #define MIPS_TBIAP() mips3_TBIAP(mips_num_tlb_entries)
229 1.58.2.2 nathanw #define MIPS_TBIS mips3_TBIS
230 1.58.2.2 nathanw #define MachTLBUpdate mips3_TLBUpdate
231 1.58.2.2 nathanw #define proc_trampoline mips3_proc_trampoline
232 1.58.2.2 nathanw #define wbflush() mips3_wbflush()
233 1.58.2.2 nathanw #elif !defined(MIPS1) && !defined(MIPS3) && defined(MIPS32) && !defined(MIPS64)
234 1.58.2.2 nathanw #define MachSetPID mips32_SetPID
235 1.58.2.2 nathanw #define MIPS_TBIAP() mips32_TBIAP(mips_num_tlb_entries)
236 1.58.2.2 nathanw #define MIPS_TBIS mips32_TBIS
237 1.58.2.2 nathanw #define MachTLBUpdate mips32_TLBUpdate
238 1.58.2.2 nathanw #define proc_trampoline mips32_proc_trampoline
239 1.58.2.2 nathanw #define wbflush() mips32_wbflush()
240 1.58.2.2 nathanw #elif !defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && defined(MIPS64)
241 1.58.2.2 nathanw /* all common with mips3 */
242 1.58.2.2 nathanw #define MachSetPID mips64_SetPID
243 1.58.2.2 nathanw #define MIPS_TBIAP() mips64_TBIAP(mips_num_tlb_entries)
244 1.58.2.2 nathanw #define MIPS_TBIS mips64_TBIS
245 1.58.2.2 nathanw #define MachTLBUpdate mips64_TLBUpdate
246 1.58.2.2 nathanw #define proc_trampoline mips64_proc_trampoline
247 1.58.2.2 nathanw #define wbflush() mips64_wbflush()
248 1.58.2.2 nathanw #elif !defined(MIPS1) && defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && defined(MIPS3_5900)
249 1.58.2.2 nathanw #define MachSetPID mips5900_SetPID
250 1.58.2.2 nathanw #define MIPS_TBIAP() mips5900_TBIAP(mips_num_tlb_entries)
251 1.58.2.2 nathanw #define MIPS_TBIS mips5900_TBIS
252 1.58.2.2 nathanw #define MachTLBUpdate mips5900_TLBUpdate
253 1.58.2.2 nathanw #define proc_trampoline mips5900_proc_trampoline
254 1.58.2.2 nathanw #define wbflush() mips5900_wbflush()
255 1.58.2.2 nathanw #else
256 1.58.2.2 nathanw #define MachSetPID (*(mips_locore_jumpvec.setTLBpid))
257 1.58.2.2 nathanw #define MIPS_TBIAP() (*(mips_locore_jumpvec.TBIAP))(mips_num_tlb_entries)
258 1.58.2.2 nathanw #define MIPS_TBIS (*(mips_locore_jumpvec.TBIS))
259 1.58.2.2 nathanw #define MachTLBUpdate (*(mips_locore_jumpvec.tlbUpdate))
260 1.58.2.2 nathanw #define wbflush() (*(mips_locore_jumpvec.wbflush))()
261 1.58.2.2 nathanw #define proc_trampoline (mips_locoresw[1])
262 1.58.2.2 nathanw #endif
263 1.58.2.2 nathanw
264 1.58.2.2 nathanw #define CPU_IDLE (mips_locoresw[2])
265 1.58.2.2 nathanw
266 1.58.2.2 nathanw /* cpu_switch_resume is called inside locore.S */
267 1.58.2.2 nathanw
268 1.58.2.2 nathanw /*
269 1.58.2.2 nathanw * CPU identification, from PRID register.
270 1.58.2.2 nathanw */
271 1.58.2.2 nathanw typedef int mips_prid_t;
272 1.58.2.2 nathanw
273 1.58.2.2 nathanw #define MIPS_PRID_REV(x) (((x) >> 0) & 0x00ff)
274 1.58.2.2 nathanw #define MIPS_PRID_IMPL(x) (((x) >> 8) & 0x00ff)
275 1.58.2.2 nathanw
276 1.58.2.2 nathanw /* pre-MIPS32/64 */
277 1.58.2.2 nathanw #define MIPS_PRID_RSVD(x) (((x) >> 16) & 0xffff)
278 1.58.2.2 nathanw #define MIPS_PRID_REV_MIN(x) ((MIPS_PRID_REV(x) >> 0) & 0x0f)
279 1.58.2.2 nathanw #define MIPS_PRID_REV_MAJ(x) ((MIPS_PRID_REV(x) >> 4) & 0x0f)
280 1.58.2.2 nathanw
281 1.58.2.2 nathanw /* MIPS32/64 */
282 1.58.2.2 nathanw #define MIPS_PRID_CID(x) (((x) >> 16) & 0x00ff) /* Company ID */
283 1.58.2.2 nathanw #define MIPS_PRID_CID_PREHISTORIC 0x00 /* Not MIPS32/64 */
284 1.58.2.2 nathanw #define MIPS_PRID_CID_MTI 0x01 /* MIPS Technologies, Inc. */
285 1.58.2.2 nathanw #define MIPS_PRID_CID_BROADCOM 0x02 /* Broadcom */
286 1.58.2.2 nathanw #define MIPS_PRID_CID_ALCHEMY 0x03 /* Alchemy Semiconductor */
287 1.58.2.2 nathanw #define MIPS_PRID_CID_SIBYTE 0x04 /* SiByte */
288 1.58.2.2 nathanw #define MIPS_PRID_CID_SANDCRAFT 0x05 /* SandCraft */
289 1.58.2.2 nathanw #define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */
290 1.58.2.2 nathanw
291 1.58.2.2 nathanw #ifdef _KERNEL
292 1.58.2.2 nathanw /*
293 1.58.2.2 nathanw * Global variables used to communicate CPU type, and parameters
294 1.58.2.2 nathanw * such as cache size, from locore to higher-level code (e.g., pmap).
295 1.58.2.2 nathanw */
296 1.58.2.2 nathanw
297 1.58.2.2 nathanw extern mips_prid_t cpu_id;
298 1.58.2.2 nathanw extern mips_prid_t fpu_id;
299 1.58.2.2 nathanw extern int mips_num_tlb_entries;
300 1.58.2.2 nathanw
301 1.58.2.2 nathanw void mips_pagecopy(caddr_t dst, caddr_t src);
302 1.58.2.2 nathanw void mips_pagezero(caddr_t dst);
303 1.58.2.2 nathanw
304 1.58.2.2 nathanw #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
305 1.58.2.2 nathanw void mips_machdep_cache_config(void);
306 1.58.2.2 nathanw #endif
307 1.58.2.2 nathanw
308 1.58.2.2 nathanw /*
309 1.58.2.2 nathanw * trapframe argument passed to trap()
310 1.58.2.2 nathanw */
311 1.58.2.2 nathanw struct trapframe {
312 1.58.2.2 nathanw mips_reg_t tf_regs[17];
313 1.58.2.2 nathanw mips_reg_t tf_ra;
314 1.58.2.2 nathanw mips_reg_t tf_sr;
315 1.58.2.2 nathanw mips_reg_t tf_mullo;
316 1.58.2.2 nathanw mips_reg_t tf_mulhi;
317 1.58.2.2 nathanw mips_reg_t tf_epc; /* may be changed by trap() call */
318 1.58.2.2 nathanw u_int32_t tf_ppl; /* previous priority level */
319 1.58.2.2 nathanw int32_t tf_pad; /* for 8 byte aligned */
320 1.58.2.2 nathanw };
321 1.58.2.2 nathanw
322 1.58.2.2 nathanw /*
323 1.58.2.2 nathanw * Stack frame for kernel traps. four args passed in registers.
324 1.58.2.2 nathanw * A trapframe is pointed to by the 5th arg, and a dummy sixth argument
325 1.58.2.2 nathanw * is used to avoid alignment problems
326 1.58.2.2 nathanw */
327 1.58.2.2 nathanw
328 1.58.2.2 nathanw struct kernframe {
329 1.58.2.2 nathanw register_t cf_args[4 + 1];
330 1.58.2.2 nathanw register_t cf_pad; /* (for 8 word alignment) */
331 1.58.2.2 nathanw register_t cf_sp;
332 1.58.2.2 nathanw register_t cf_ra;
333 1.58.2.2 nathanw struct trapframe cf_frame;
334 1.58.2.2 nathanw };
335 1.58.2.3 nathanw #endif /* _KERNEL */
336 1.58.2.2 nathanw #endif /* _MIPS_LOCORE_H */
337