xref: /netbsd/sys/arch/mips/include/cpu.h (revision 6550d01e)
1 /*	$NetBSD: cpu.h,v 1.97 2011/01/26 01:18:54 pooka Exp $	*/
2 
3 /*-
4  * Copyright (c) 1992, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Ralph Campbell and Rick Macklem.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)cpu.h	8.4 (Berkeley) 1/4/94
35  */
36 
37 #ifndef _CPU_H_
38 #define _CPU_H_
39 
40 #include <mips/cpuregs.h>
41 
42 /*
43  * Exported definitions unique to NetBSD/mips cpu support.
44  */
45 
46 #ifdef _KERNEL
47 #ifndef _LOCORE
48 #include <sys/cpu_data.h>
49 
50 #if defined(_KERNEL_OPT)
51 #include "opt_lockdebug.h"
52 #endif
53 
54 struct pridtab {
55 	int	cpu_cid;
56 	int	cpu_pid;
57 	int	cpu_rev;	/* -1 == wildcard */
58 	int	cpu_copts;	/* -1 == wildcard */
59 	int	cpu_isa;	/* -1 == probed (mips32/mips64) */
60 	int	cpu_ntlb;	/* -1 == unknown, 0 == probed */
61 	int	cpu_flags;
62 	u_int	cpu_cp0flags;	/* presence of some cp0 regs */
63 	u_int	cpu_cidflags;	/* company-specific flags */
64 	const char	*cpu_displayname;
65 };
66 
67 extern const struct pridtab *mycpu;
68 
69 /*
70  * bitfield defines for cpu_cp0flags
71  */
72 #define  MIPS_CP0FL_USE		__BIT(0)	/* use these flags */
73 #define  MIPS_CP0FL_ECC		__BIT(1)
74 #define  MIPS_CP0FL_CACHE_ERR	__BIT(2)
75 #define  MIPS_CP0FL_EIRR	__BIT(3)
76 #define  MIPS_CP0FL_EIMR	__BIT(4)
77 #define  MIPS_CP0FL_EBASE	__BIT(5)
78 #define  MIPS_CP0FL_CONFIG	__BIT(6)
79 #define  MIPS_CP0FL_CONFIGn(n)	(__BIT(7) << ((n) & 7))
80 
81 /*
82  * cpu_cidflags defines, by company
83  */
84 /*
85  * RMI company-specific cpu_cidflags
86  */
87 #define MIPS_CIDFL_RMI_TYPE     __BITS(0,2)
88 #define  CIDFL_RMI_TYPE_XLR     0
89 #define  CIDFL_RMI_TYPE_XLS     1
90 #define  CIDFL_RMI_TYPE_XLP     2
91 
92 
93 struct cpu_info {
94 	struct cpu_data ci_data;	/* MI per-cpu data */
95 	struct cpu_info *ci_next;	/* Next CPU in list */
96 	cpuid_t ci_cpuid;		/* Machine-level identifier */
97 	u_long ci_cpu_freq;		/* CPU frequency */
98 	u_long ci_cycles_per_hz;	/* CPU freq / hz */
99 	u_long ci_divisor_delay;	/* for delay/DELAY */
100 	u_long ci_divisor_recip;	/* unused, for obsolete microtime(9) */
101 	struct lwp *ci_curlwp;		/* currently running lwp */
102 	struct lwp *ci_fpcurlwp;	/* the current FPU owner */
103 	int ci_want_resched;		/* user preemption pending */
104 	int ci_mtx_count;		/* negative count of held mutexes */
105 	int ci_mtx_oldspl;		/* saved SPL value */
106 	int ci_idepth;			/* hardware interrupt depth */
107 };
108 
109 #define	CPU_INFO_ITERATOR		int
110 #define	CPU_INFO_FOREACH(cii, ci)	\
111     (void)(cii), ci = &cpu_info_store; ci != NULL; ci = ci->ci_next
112 
113 #endif /* !_LOCORE */
114 #endif /* _KERNEL */
115 
116 /*
117  * CTL_MACHDEP definitions.
118  */
119 #define CPU_CONSDEV		1	/* dev_t: console terminal device */
120 #define CPU_BOOTED_KERNEL	2	/* string: booted kernel name */
121 #define CPU_ROOT_DEVICE		3	/* string: root device name */
122 #define CPU_LLSC		4	/* OS/CPU supports LL/SC instruction */
123 
124 /*
125  * Platform can override, but note this breaks userland compatibility
126  * with other mips platforms.
127  */
128 #ifndef CPU_MAXID
129 #define CPU_MAXID		5	/* number of valid machdep ids */
130 
131 #endif
132 
133 #ifdef _KERNEL
134 #if defined(_LKM) || defined(_STANDALONE)
135 /* Assume all CPU architectures are valid for LKM's and standlone progs */
136 #define	MIPS1	1
137 #define	MIPS3	1
138 #define	MIPS4	1
139 #define	MIPS32	1
140 #define	MIPS64	1
141 #endif
142 
143 #if (MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS64) == 0
144 #error at least one of MIPS1, MIPS3, MIPS4, MIPS32 or MIPS64 must be specified
145 #endif
146 
147 /* Shortcut for MIPS3 or above defined */
148 #if defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64)
149 #define	MIPS3_PLUS	1
150 #else
151 #undef MIPS3_PLUS
152 #endif
153 
154 /*
155  * Macros to find the CPU architecture we're on at run-time,
156  * or if possible, at compile-time.
157  */
158 
159 #define	CPU_ARCH_MIPSx	0		/* XXX unknown */
160 #define	CPU_ARCH_MIPS1	(1 << 0)
161 #define	CPU_ARCH_MIPS2	(1 << 1)
162 #define	CPU_ARCH_MIPS3	(1 << 2)
163 #define	CPU_ARCH_MIPS4	(1 << 3)
164 #define	CPU_ARCH_MIPS5	(1 << 4)
165 #define	CPU_ARCH_MIPS32	(1 << 5)
166 #define	CPU_ARCH_MIPS64	(1 << 6)
167 
168 /* Note: must be kept in sync with -ffixed-?? Makefile.mips. */
169 #define MIPS_CURLWP             $23
170 #define MIPS_CURLWP_QUOTED      "$23"
171 #define MIPS_CURLWP_CARD	23
172 #define	MIPS_CURLWP_FRAME(x)	FRAME_S7(x)
173 
174 #ifndef _LOCORE
175 
176 extern struct cpu_info cpu_info_store;
177 register struct lwp *mips_curlwp asm(MIPS_CURLWP_QUOTED);
178 
179 #define	curlwp			mips_curlwp
180 #define	curcpu()		(curlwp->l_cpu)
181 #define	curpcb			((struct pcb *)lwp_getpcb(curlwp))
182 #define	fpcurlwp		(curcpu()->ci_fpcurlwp)
183 #define	cpu_number()		(0)
184 #define	cpu_proc_fork(p1, p2)	((void)((p2)->p_md.md_abi = (p1)->p_md.md_abi))
185 
186 /* XXX simonb
187  * Should the following be in a cpu_info type structure?
188  * And how many of these are per-cpu vs. per-system?  (Ie,
189  * we can assume that all cpus have the same mmu-type, but
190  * maybe not that all cpus run at the same clock speed.
191  * Some SGI's apparently support R12k and R14k in the same
192  * box.)
193  */
194 extern int cpu_arch;
195 extern int mips_cpu_flags;
196 extern int mips_has_r4k_mmu;
197 extern int mips_has_llsc;
198 extern int mips3_pg_cached;
199 #ifdef _LP64
200 extern uint64_t mips3_xkphys_cached;
201 #endif
202 extern u_int mips3_pg_shift;
203 
204 #define	CPU_MIPS_R4K_MMU		0x0001
205 #define	CPU_MIPS_NO_LLSC		0x0002
206 #define	CPU_MIPS_CAUSE_IV		0x0004
207 #define	CPU_MIPS_HAVE_SPECIAL_CCA	0x0008	/* Defaults to '3' if not set. */
208 #define	CPU_MIPS_CACHED_CCA_MASK	0x0070
209 #define	CPU_MIPS_CACHED_CCA_SHIFT	 4
210 #define	CPU_MIPS_DOUBLE_COUNT		0x0080	/* 1 cp0 count == 2 clock cycles */
211 #define	CPU_MIPS_USE_WAIT		0x0100	/* Use "wait"-based cpu_idle() */
212 #define	CPU_MIPS_NO_WAIT		0x0200	/* Inverse of previous, for mips32/64 */
213 #define	CPU_MIPS_D_CACHE_COHERENT	0x0400	/* D-cache is fully coherent */
214 #define	CPU_MIPS_I_D_CACHE_COHERENT	0x0800	/* I-cache funcs don't need to flush the D-cache */
215 #define	CPU_MIPS_NO_LLADDR		0x1000
216 #define	CPU_MIPS_HAVE_MxCR		0x2000	/* have mfcr, mtcr insns */
217 #define	MIPS_NOT_SUPP			0x8000
218 
219 #endif	/* !_LOCORE */
220 
221 #if ((MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS64) == 1) || defined(_LOCORE)
222 
223 #if defined(MIPS1)
224 
225 # define CPUISMIPS3		0
226 # define CPUIS64BITS		0
227 # define CPUISMIPS32		0
228 # define CPUISMIPS64		0
229 # define CPUISMIPSNN		0
230 # define MIPS_HAS_R4K_MMU	0
231 # define MIPS_HAS_CLOCK		0
232 # define MIPS_HAS_LLSC		0
233 # define MIPS_HAS_LLADDR	0
234 
235 #elif defined(MIPS3) || defined(MIPS4)
236 
237 # define CPUISMIPS3		1
238 # define CPUIS64BITS		1
239 # define CPUISMIPS32		0
240 # define CPUISMIPS64		0
241 # define CPUISMIPSNN		0
242 # define MIPS_HAS_R4K_MMU	1
243 # define MIPS_HAS_CLOCK		1
244 # if defined(_LOCORE)
245 #  if !defined(MIPS3_5900) && !defined(MIPS3_4100)
246 #   define MIPS_HAS_LLSC	1
247 #  else
248 #   define MIPS_HAS_LLSC	0
249 #  endif
250 # else	/* _LOCORE */
251 #  define MIPS_HAS_LLSC		(mips_has_llsc)
252 # endif	/* _LOCORE */
253 # define MIPS_HAS_LLADDR	((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
254 
255 #elif defined(MIPS32)
256 
257 # define CPUISMIPS3		1
258 # define CPUIS64BITS		0
259 # define CPUISMIPS32		1
260 # define CPUISMIPS64		0
261 # define CPUISMIPSNN		1
262 # define MIPS_HAS_R4K_MMU	1
263 # define MIPS_HAS_CLOCK		1
264 # define MIPS_HAS_LLSC		1
265 # define MIPS_HAS_LLADDR	((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
266 
267 #elif defined(MIPS64)
268 
269 # define CPUISMIPS3		1
270 # define CPUIS64BITS		1
271 # define CPUISMIPS32		0
272 # define CPUISMIPS64		1
273 # define CPUISMIPSNN		1
274 # define MIPS_HAS_R4K_MMU	1
275 # define MIPS_HAS_CLOCK		1
276 # define MIPS_HAS_LLSC		1
277 # define MIPS_HAS_LLADDR	((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
278 
279 #endif
280 
281 #else /* run-time test */
282 
283 #ifndef	_LOCORE
284 
285 #define	MIPS_HAS_R4K_MMU	(mips_has_r4k_mmu)
286 #define	MIPS_HAS_LLSC		(mips_has_llsc)
287 #define	MIPS_HAS_LLADDR		((mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
288 
289 /* This test is ... rather bogus */
290 #define	CPUISMIPS3	((cpu_arch & \
291 	(CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS32 | CPU_ARCH_MIPS64)) != 0)
292 
293 /* And these aren't much better while the previous test exists as is... */
294 #define	CPUISMIPS32	((cpu_arch & CPU_ARCH_MIPS32) != 0)
295 #define	CPUISMIPS64	((cpu_arch & CPU_ARCH_MIPS64) != 0)
296 #define	CPUISMIPSNN	((cpu_arch & (CPU_ARCH_MIPS32 | CPU_ARCH_MIPS64)) != 0)
297 #define	CPUIS64BITS	((cpu_arch & \
298 	(CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS64)) != 0)
299 
300 #define	MIPS_HAS_CLOCK	(cpu_arch >= CPU_ARCH_MIPS3)
301 
302 #else	/* !_LOCORE */
303 
304 #define	MIPS_HAS_LLSC	0
305 
306 #endif	/* !_LOCORE */
307 
308 #endif /* run-time test */
309 
310 #ifndef	_LOCORE
311 
312 /*
313  * definitions of cpu-dependent requirements
314  * referenced in generic code
315  */
316 
317 void cpu_intr(uint32_t, uint32_t, vaddr_t, uint32_t);
318 
319 /*
320  * Arguments to hardclock and gatherstats encapsulate the previous
321  * machine state in an opaque clockframe.
322  */
323 struct clockframe {
324 	vaddr_t	pc;	/* program counter at time of interrupt */
325 	uint32_t	sr;	/* status register at time of interrupt */
326 	u_int		ppl;	/* previous priority level at time of interrupt */
327 };
328 
329 /*
330  * A port must provde CLKF_USERMODE() for use in machine-independent code.
331  * These differ on r4000 and r3000 systems; provide them in the
332  * port-dependent file that includes this one, using the macros below.
333  */
334 
335 /* mips1 versions */
336 #define	MIPS1_CLKF_USERMODE(framep)	((framep)->sr & MIPS_SR_KU_PREV)
337 
338 /* mips3 versions */
339 #define	MIPS3_CLKF_USERMODE(framep)	((framep)->sr & MIPS_SR_KSU_USER)
340 
341 #define	CLKF_PC(framep)		((framep)->pc)
342 #define	CLKF_INTR(framep)	(0)
343 
344 #if defined(MIPS3_PLUS) && !defined(MIPS1)		/* XXX bogus! */
345 #define	CLKF_USERMODE(framep)	MIPS3_CLKF_USERMODE(framep)
346 #endif
347 
348 #if !defined(MIPS3_PLUS) && defined(MIPS1)		/* XXX bogus! */
349 #define	CLKF_USERMODE(framep)	MIPS1_CLKF_USERMODE(framep)
350 #endif
351 
352 #if defined(MIPS3_PLUS) && defined(MIPS1)		/* XXX bogus! */
353 #define CLKF_USERMODE(framep) \
354     ((CPUISMIPS3) ? MIPS3_CLKF_USERMODE(framep):  MIPS1_CLKF_USERMODE(framep))
355 #endif
356 
357 /*
358  * This is used during profiling to integrate system time.  It can safely
359  * assume that the process is resident.
360  */
361 #define	LWP_PC(l)							\
362 	(((struct frame *)(l)->l_md.md_regs)->f_regs[37])	/* XXX PC */
363 
364 /*
365  * Preempt the current process if in interrupt from user mode,
366  * or after the current trap/syscall if in system mode.
367  */
368 void	cpu_need_resched(struct cpu_info *, int);
369 
370 /*
371  * Give a profiling tick to the current process when the user profiling
372  * buffer pages are invalid.  On the MIPS, request an ast to send us
373  * through trap, marking the proc as needing a profiling tick.
374  */
375 #define	cpu_need_proftick(l)						\
376 do {									\
377 	(l)->l_pflag |= LP_OWEUPC;					\
378 	aston(l);							\
379 } while (/*CONSTCOND*/0)
380 
381 /*
382  * Notify the current lwp (l) that it has a signal pending,
383  * process as soon as possible.
384  */
385 #define	cpu_signotify(l)	aston(l)
386 
387 #define aston(l)		((l)->l_md.md_astpending = 1)
388 
389 /*
390  * Misc prototypes and variable declarations.
391  */
392 struct lwp;
393 struct pcb;
394 
395 extern struct segtab *segbase;	/* current segtab base */
396 
397 /* copy.S */
398 int8_t	ufetch_int8(void *);
399 int16_t	ufetch_int16(void *);
400 int32_t ufetch_int32(void *);
401 uint8_t	ufetch_uint8(void *);
402 uint16_t ufetch_uint16(void *);
403 uint32_t ufetch_uint32(void *);
404 int8_t	ufetch_int8_intrsafe(void *);
405 int16_t	ufetch_int16_intrsafe(void *);
406 int32_t ufetch_int32_intrsafe(void *);
407 uint8_t	ufetch_uint8_intrsafe(void *);
408 uint16_t ufetch_uint16_intrsafe(void *);
409 uint32_t ufetch_uint32_intrsafe(void *);
410 #ifdef _LP64
411 int64_t ufetch_int64(void *);
412 uint64_t ufetch_uint64(void *);
413 int64_t ufetch_int64_intrsafe(void *);
414 uint64_t ufetch_uint64_intrsafe(void *);
415 #endif
416 char	ufetch_char(void *);
417 short	ufetch_short(void *);
418 int	ufetch_int(void *);
419 long	ufetch_long(void *);
420 char	ufetch_char_intrsafe(void *);
421 short	ufetch_short_intrsafe(void *);
422 int	ufetch_int_intrsafe(void *);
423 long	ufetch_long_intrsafe(void *);
424 
425 u_char	ufetch_uchar(void *);
426 u_short	ufetch_ushort(void *);
427 u_int	ufetch_uint(void *);
428 u_long	ufetch_ulong(void *);
429 u_char	ufetch_uchar_intrsafe(void *);
430 u_short	ufetch_ushort_intrsafe(void *);
431 u_int	ufetch_uint_intrsafe(void *);
432 u_long	ufetch_ulong_intrsafe(void *);
433 void 	*ufetch_ptr(void *);
434 
435 int	ustore_int8(void *, int8_t);
436 int	ustore_int16(void *, int16_t);
437 int	ustore_int32(void *, int32_t);
438 int	ustore_uint8(void *, uint8_t);
439 int	ustore_uint16(void *, uint16_t);
440 int	ustore_uint32(void *, uint32_t);
441 int	ustore_int8_intrsafe(void *, int8_t);
442 int	ustore_int16_intrsafe(void *, int16_t);
443 int	ustore_int32_intrsafe(void *, int32_t);
444 int	ustore_uint8_intrsafe(void *, uint8_t);
445 int	ustore_uint16_intrsafe(void *, uint16_t);
446 int	ustore_uint32_intrsafe(void *, uint32_t);
447 #ifdef _LP64
448 int	ustore_int64(void *, int64_t);
449 int	ustore_uint64(void *, uint64_t);
450 int	ustore_int64_intrsafe(void *, int64_t);
451 int	ustore_uint64_intrsafe(void *, uint64_t);
452 #endif
453 int	ustore_char(void *, char);
454 int	ustore_char_intrsafe(void *, char);
455 int	ustore_short(void *, short);
456 int	ustore_short_intrsafe(void *, short);
457 int	ustore_int(void *, int);
458 int	ustore_int_intrsafe(void *, int);
459 int	ustore_long(void *, long);
460 int	ustore_long_intrsafe(void *, long);
461 int	ustore_uchar(void *, u_char);
462 int	ustore_uchar_intrsafe(void *, u_char);
463 int	ustore_ushort(void *, u_short);
464 int	ustore_ushort_intrsafe(void *, u_short);
465 int	ustore_uint(void *, u_int);
466 int	ustore_uint_intrsafe(void *, u_int);
467 int	ustore_ulong(void *, u_long);
468 int	ustore_ulong_intrsafe(void *, u_long);
469 int 	ustore_ptr(void *, void *);
470 int	ustore_ptr_intrsafe(void *, void *);
471 
472 int	ustore_uint32_isync(void *, uint32_t);
473 
474 /* trap.c */
475 void	netintr(void);
476 int	kdbpeek(vaddr_t);
477 
478 /* mips_machdep.c */
479 void	dumpsys(void);
480 int	savectx(struct pcb *);
481 void	mips_init_msgbuf(void);
482 void	mips_init_lwp0_uarea(void);
483 void	savefpregs(struct lwp *);
484 void	loadfpregs(struct lwp *);
485 int	ioaccess(vaddr_t, paddr_t, vsize_t);
486 int	iounaccess(vaddr_t, vsize_t);
487 
488 /* locore*.S */
489 int	badaddr(void *, size_t);
490 int	badaddr64(uint64_t, size_t);
491 
492 /* mips_machdep.c */
493 void	cpu_identify(void);
494 void	mips_vector_init(void);
495 
496 #endif /* ! _LOCORE */
497 #endif /* _KERNEL */
498 #endif /* _CPU_H_ */
499