]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/include/alpha_cpu.h
This commit was generated by cvs2svn to compensate for changes in r155518,
[FreeBSD/FreeBSD.git] / sys / alpha / include / alpha_cpu.h
1 /* $FreeBSD$ */
2 /* From: NetBSD: alpha_cpu.h,v 1.15 1997/09/20 19:02:34 mjacob Exp */
3
4 /*-
5  * Copyright (c) 1996 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Chris G. Demetriou
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30
31 #ifndef __ALPHA_ALPHA_CPU_H__
32 #define __ALPHA_ALPHA_CPU_H__
33
34 /*
35  * Alpha CPU + OSF/1 PALcode definitions for use by the kernel.
36  *
37  * Definitions for:
38  *
39  *      Process Control Block
40  *      Interrupt/Exception/Syscall Stack Frame
41  *      Processor Status Register
42  *      Machine Check Error Summary Register
43  *      Machine Check Logout Area
44  *      Virtual Memory Management
45  *      Kernel Entry Vectors
46  *      MMCSR Fault Type Codes
47  *      Translation Buffer Invalidation
48  *
49  * and miscellaneous PALcode operations.
50  */
51
52
53 /*
54  * Process Control Block definitions [OSF/1 PALcode Specific]
55  */
56
57 struct alpha_pcb {
58         unsigned long   apcb_ksp;       /* kernel stack ptr */
59         unsigned long   apcb_usp;       /* user stack ptr */
60         unsigned long   apcb_ptbr;      /* page table base reg */
61         unsigned int    apcb_cpc;       /* charged process cycles */
62         unsigned int    apcb_asn;       /* address space number */
63         unsigned long   apcb_unique;    /* process unique value */
64         unsigned long   apcb_flags;     /* flags; see below */
65         unsigned long   apcb_decrsv0;   /* DEC reserved */
66         unsigned long   apcb_decrsv1;   /* DEC reserved */
67 };
68
69 #define ALPHA_PCB_FLAGS_FEN     0x0000000000000001
70 #define ALPHA_PCB_FLAGS_PME     0x4000000000000000
71
72 /*
73  * Interrupt/Exception/Syscall "Hardware" (really PALcode)
74  * Stack Frame definitions
75  *
76  * These are quadword offsets from the sp on kernel entry, i.e.
77  * to get to the value in question you access (sp + (offset * 8)).
78  *
79  * On syscall entry, A0-A2 aren't written to memory but space
80  * _is_ reserved for them.
81  */
82
83 #define ALPHA_HWFRAME_PS        0       /* processor status register */
84 #define ALPHA_HWFRAME_PC        1       /* program counter */
85 #define ALPHA_HWFRAME_GP        2       /* global pointer */
86 #define ALPHA_HWFRAME_A0        3       /* a0 */
87 #define ALPHA_HWFRAME_A1        4       /* a1 */
88 #define ALPHA_HWFRAME_A2        5       /* a2 */
89
90 #define ALPHA_HWFRAME_SIZE      6       /* 6 8-byte words */
91
92 /*
93  * Processor Status Register [OSF/1 PALcode Specific]
94  *
95  * Includes user/kernel mode bit, interrupt priority levels, etc.
96  */
97
98 #define ALPHA_PSL_USERMODE      0x0008          /* set -> user mode */
99 #define ALPHA_PSL_IPL_MASK      0x0007          /* interrupt level mask */
100
101 #define ALPHA_PSL_IPL_0         0x0000          /* all interrupts enabled */
102 #define ALPHA_PSL_IPL_SOFT      0x0001          /* software ints disabled */
103 #define ALPHA_PSL_IPL_IO        0x0004          /* I/O dev ints disabled */
104 #define ALPHA_PSL_IPL_CLOCK     0x0005          /* clock ints disabled */
105 #define ALPHA_PSL_IPL_HIGH      0x0006          /* all but mchecks disabled */
106 #define ALPHA_PSL_IPL_MCES      0x0007          /* all interrupts disabled */
107
108 #define ALPHA_PSL_MUST_BE_ZERO  0xfffffffffffffff0
109
110 /* Convenience constants: what must be set/clear in user mode */
111 #define ALPHA_PSL_USERSET       ALPHA_PSL_USERMODE
112 #define ALPHA_PSL_USERCLR       (ALPHA_PSL_MUST_BE_ZERO | ALPHA_PSL_IPL_MASK)
113
114 /*
115  * Interrupt Type Code Definitions [OSF/1 PALcode Specific]
116  */
117  
118 #define ALPHA_INTR_XPROC        0       /* interprocessor interrupt */
119 #define ALPHA_INTR_CLOCK        1       /* clock interrupt */
120 #define ALPHA_INTR_ERROR        2       /* correctable error or mcheck */
121 #define ALPHA_INTR_DEVICE       3       /* device interrupt */
122 #define ALPHA_INTR_PERF         4       /* performance counter */
123 #define ALPHA_INTR_PASSIVE      5       /* passive release */
124
125 /*
126  * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific]
127  *
128  * The following bits are values as read.  On write, _PCE, _SCE, and
129  * _MIP are "write 1 to clear."
130  */
131
132 #define ALPHA_MCES_IMP                                                  \
133     0xffffffff00000000  /* impl. dependent */
134 #define ALPHA_MCES_RSVD                                                 \
135     0x00000000ffffffe0  /* reserved */
136 #define ALPHA_MCES_DSC                                                  \
137     0x0000000000000010  /* disable system correctable error reporting */
138 #define ALPHA_MCES_DPC                                                  \
139     0x0000000000000008  /* disable processor correctable error reporting */
140 #define ALPHA_MCES_PCE                                                  \
141     0x0000000000000004  /* processor correctable error in progress */
142 #define ALPHA_MCES_SCE                                                  \
143     0x0000000000000002  /* system correctable error in progress */
144 #define ALPHA_MCES_MIP                                                  \
145     0x0000000000000001  /* machine check in progress */
146
147 /*
148  * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific]
149  */
150
151 struct alpha_logout_area {
152         unsigned int    la_frame_size;          /* frame size */
153         unsigned int    la_flags;               /* flags; see below */
154         unsigned int    la_cpu_offset;          /* offset to cpu area */
155         unsigned int    la_system_offset;       /* offset to system area */
156 };
157
158 #define ALPHA_LOGOUT_FLAGS_RETRY        0x80000000      /* OK to continue */
159 #define ALPHA_LOGOUT_FLAGS_SE           0x40000000      /* second error */
160 #define ALPHA_LOGOUT_FLAGS_SBZ          0x3fffffff      /* should be zero */
161
162 #define ALPHA_LOGOUT_NOT_BUILT                                          \
163     (struct alpha_logout_area *)0xffffffffffffffff)
164
165 #define ALPHA_LOGOUT_PAL_AREA(lap)                                      \
166     (unsigned long *)((unsigned char *)(lap) + 16)
167 #define ALPHA_LOGOUT_PAL_SIZE(lap)                                      \
168     ((lap)->la_cpu_offset - 16)
169 #define ALPHA_LOGOUT_CPU_AREA(lap)                                      \
170     (unsigned long *)((unsigned char *)(lap) + (lap)->la_cpu_offset)
171 #define ALPHA_LOGOUT_CPU_SIZE(lap)                                      \
172     ((lap)->la_system_offset - (lap)->la_cpu_offset)
173 #define ALPHA_LOGOUT_SYSTEM_AREA(lap)                                   \
174     (unsigned long *)((unsigned char *)(lap) + (lap)->la_system_offset)
175 #define ALPHA_LOGOUT_SYSTEM_SIZE(lap)                                   \
176     ((lap)->la_frame_size - (lap)->la_system_offset)
177         
178 /*
179  * Virtual Memory Management definitions [OSF/1 PALcode Specific]
180  *
181  * Includes user and kernel space addresses and information,
182  * page table entry definitions, etc.
183  *
184  * NOTE THAT THESE DEFINITIONS MAY CHANGE IN FUTURE ALPHA CPUS!
185  */
186
187 #define ALPHA_PGSHIFT           13 /* bits that index within page */
188 #define ALPHA_PTSHIFT           10 /* bits that index within page tables */
189 #define ALPHA_PGBYTES           (1 << ALPHA_PGSHIFT)
190 #define ALPHA_L3SHIFT           ALPHA_PGSHIFT
191 #define ALPHA_L2SHIFT           (ALPHA_L3SHIFT+ALPHA_PTSHIFT)
192 #define ALPHA_L1SHIFT           (ALPHA_L2SHIFT+ALPHA_PTSHIFT)
193
194 #define ALPHA_USEG_BASE         0                       /* virtual */
195 #define ALPHA_USEG_END          0x000003ffffffffffLL
196
197 #define ALPHA_K0SEG_BASE        0xfffffc0000000000LL    /* direct-mapped */
198 #define ALPHA_K0SEG_END         0xfffffdffffffffffLL
199 #define ALPHA_K1SEG_BASE        0xfffffe0000000000LL    /* virtual */
200 #define ALPHA_K1SEG_END         0xffffffffffffffffLL
201
202 #define ALPHA_K0SEG_TO_PHYS(x)  ((x) & ~ALPHA_K0SEG_BASE)
203 #define ALPHA_PHYS_TO_K0SEG(x)  ((x) | ALPHA_K0SEG_BASE)
204
205 #define ALPHA_PTE_VALID                 0x0001
206
207 #define ALPHA_PTE_FAULT_ON_READ         0x0002
208 #define ALPHA_PTE_FAULT_ON_WRITE        0x0004
209 #define ALPHA_PTE_FAULT_ON_EXECUTE      0x0008
210
211 #define ALPHA_PTE_ASM                   0x0010          /* addr. space match */
212 #define ALPHA_PTE_GRANULARITY           0x0060          /* granularity hint */
213
214 #define ALPHA_PTE_PROT                  0xff00
215 #define ALPHA_PTE_KR                    0x0100
216 #define ALPHA_PTE_UR                    0x0200
217 #define ALPHA_PTE_KW                    0x1000
218 #define ALPHA_PTE_UW                    0x2000
219
220 #define ALPHA_PTE_WRITE                 (ALPHA_PTE_KW | ALPHA_PTE_UW)
221
222 #define ALPHA_PTE_SOFTWARE              0xffff0000
223
224 #define ALPHA_PTE_PFN                   0xffffffff00000000
225
226 #define ALPHA_PTE_TO_PFN(pte)           ((u_long)(pte) >> 32)
227 #define ALPHA_PTE_FROM_PFN(pfn)         ((u_long)(pfn) << 32)
228
229 typedef unsigned long alpha_pt_entry_t;
230
231 /*
232  * Kernel Entry Vectors.  [OSF/1 PALcode Specific]
233  */
234
235 #define ALPHA_KENTRY_INT        0
236 #define ALPHA_KENTRY_ARITH      1
237 #define ALPHA_KENTRY_MM         2
238 #define ALPHA_KENTRY_IF         3
239 #define ALPHA_KENTRY_UNA        4
240 #define ALPHA_KENTRY_SYS        5
241
242 /*
243  * MMCSR Fault Type Codes.  [OSF/1 PALcode Specific]
244  */
245
246 #define ALPHA_MMCSR_INVALTRANS  0
247 #define ALPHA_MMCSR_ACCESS      1
248 #define ALPHA_MMCSR_FOR         2
249 #define ALPHA_MMCSR_FOE         3
250 #define ALPHA_MMCSR_FOW         4
251
252 /*
253  * Instruction Fault Type Codes.  [OSF/1 PALcode Specific]
254  */
255
256 #define ALPHA_IF_CODE_BPT       0
257 #define ALPHA_IF_CODE_BUGCHK    1
258 #define ALPHA_IF_CODE_GENTRAP   2
259 #define ALPHA_IF_CODE_FEN       3
260 #define ALPHA_IF_CODE_OPDEC     4
261
262 /*
263  * Translation Buffer Invalidation definitions [OSF/1 PALcode Specific]
264  */
265
266 #define ALPHA_TBIA()    alpha_pal_tbi(-2, 0)            /* all TB entries */
267 #define ALPHA_TBIAP()   alpha_pal_tbi(-1, 0)            /* all per-process */
268 #define ALPHA_TBISI(va) alpha_pal_tbi(1, (va))          /* ITB entry for va */
269 #define ALPHA_TBISD(va) alpha_pal_tbi(2, (va))          /* DTB entry for va */
270 #define ALPHA_TBIS(va)  alpha_pal_tbi(3, (va))          /* all for va */
271
272 /*
273  * Bits used in the amask instruction [EV56 and later]
274  */
275
276 #define ALPHA_AMASK_BWX         0x0001          /* byte/word extension */
277 #define ALPHA_AMASK_FIX         0x0002          /* sqrt and f <-> i conversion extension */
278 #define ALPHA_AMASK_CIX         0x0004          /* count extension */
279 #define ALPHA_AMASK_MVI         0x0100          /* multimedia extension */
280 #define ALPHA_AMASK_PRECISE     0x0200          /* Precise arithmetic traps */
281
282 /*
283  * Chip family IDs returned by implver instruction
284  */
285
286 #define ALPHA_IMPLVER_EV4       0               /* LCA/EV4/EV45 */
287 #define ALPHA_IMPLVER_EV5       1               /* EV5/EV56/PCA56 */
288 #define ALPHA_IMPLVER_EV6       2               /* EV6 */
289
290
291 /*
292  * Inlines for Alpha instructions normally inaccessible from C.
293  */
294
295 static __inline u_int64_t
296 alpha_amask(u_int64_t mask)
297 {
298         u_int64_t result;
299         __asm__ __volatile__ (
300                 "amask %1,%0"
301                 : "=r" (result)
302                 : "r" (mask));
303         return result;
304 }
305
306 static __inline unsigned long
307 alpha_implver(void)
308 {
309         u_int64_t result;
310         __asm__ __volatile__ (
311                 "implver %0"
312                 : "=r" (result));
313         return result;
314 }
315
316 static __inline unsigned long
317 alpha_rpcc(void)
318 {
319         u_int64_t result;
320         __asm__ __volatile__ (
321                 "rpcc %0"
322                 : "=r" (result));
323         return result;
324 }
325
326 static __inline void
327 alpha_mb(void)
328 {
329         __asm__ __volatile__ ("mb");
330 }
331
332 static __inline void
333 alpha_wmb(void)
334 {
335         /*
336          * XXX dfr: NetBSD originally had mb instead of wmb for
337          * alpha_wmb(). I'm not sure why so I'm leaving it alone. I
338          * think it should be safe to use wmb though.
339          */
340         __asm__ __volatile__ ("mb");
341 }
342
343 /*
344  * Inlines for OSF/1 PALcode operations.
345  */
346
347 static __inline void
348 alpha_pal_halt(void)
349 {
350         __asm__ __volatile__ ("call_pal 0x0 #PAL_halt");
351 }
352
353 static __inline void
354 alpha_pal_cflush(u_int64_t pfn)
355 {
356         register u_int64_t a0 __asm__("$16") = pfn;
357         __asm__ __volatile__ (
358                 "call_pal 0x1 #PAL_cflush"
359                 :
360                 : "r" (a0));
361 }
362
363 static __inline void
364 alpha_pal_draina(void)
365 {
366         __asm__ __volatile__ ("call_pal 0x2 #PAL_draina" : : : "memory");
367 }
368
369 static __inline void
370 alpha_pal_wripir(u_int64_t ipir)
371 {
372         register u_int64_t a0 __asm__("$16") = ipir;
373         __asm__ __volatile__ (
374                 "call_pal 0xd #PAL_ipir"
375                 : "+r" (a0)
376                 :
377                 : "$1", "$22", "$23", "$24", "$25");
378 }
379
380 static __inline u_int64_t
381 alpha_pal_rdmces(void)
382 {
383         register u_int64_t v0 __asm__("$0");
384         __asm__ __volatile__ (
385                 "call_pal 0x10 #PAL_OSF1_rdmces"
386                 : "=r" (v0)
387                 :
388                 : "$1", "$22", "$23", "$24", "$25");
389         return v0;
390 }
391
392 static __inline void
393 alpha_pal_wrmces(u_int64_t mces)
394 {
395         register u_int64_t a0 __asm__("$16") = mces;
396         __asm__ __volatile__ (
397                 "call_pal 0x11 #PAL_wrmces"
398                 : "+r" (a0)
399                 :
400                 : "$1", "$22", "$23", "$24", "$25");
401 }
402
403 static __inline void
404 alpha_pal_wrfen(u_int64_t fen)
405 {
406         register u_int64_t a0 __asm__("$16") = fen;
407         __asm__ __volatile__ (
408                 "call_pal 0x2b #PAL_wrfen"
409                 : "+r" (a0)
410                 :
411                 : "$1", "$22", "$23", "$24", "$25");
412 }
413
414 static __inline void
415 alpha_pal_wrvptptr(u_int64_t vptptr)
416 {
417         register u_int64_t a0 __asm__("$16") = vptptr;
418         __asm__ __volatile__ (
419                 "call_pal 0x2d #PAL_wrvptptr"
420                 : "+r" (a0)
421                 :
422                 : "$1", "$22", "$23", "$24", "$25");
423 }
424
425 static __inline u_int64_t
426 alpha_pal_swpctx(u_int64_t pcb)
427 {
428         register u_int64_t a0 __asm__("$16") = pcb;
429         register u_int64_t v0 __asm__("$0");
430         __asm__ __volatile__ (
431                 "call_pal 0x30 #PAL_OSF1_swpctx"
432                 : "=r" (v0), "+r" (a0)
433                 :
434                 : "$1", "$22", "$23", "$24", "$25", "memory");
435         return v0;
436 }
437
438 static __inline void
439 alpha_pal_wrval(u_int64_t sysvalue)
440 {
441         register u_int64_t a0 __asm__("$16") = sysvalue;
442         __asm__ __volatile__ (
443                 "call_pal 0x31 #PAL_wrval"
444                 : "+r" (a0)
445                 :
446                 : "$1", "$22", "$23", "$24", "$25");
447 }
448
449 static __inline u_int64_t
450 alpha_pal_rdval(void)
451 {
452         register u_int64_t v0 __asm__("$0");
453         __asm__ __volatile__ (
454                 "call_pal 0x32 #PAL_OSF1_rdval"
455                 : "=r" (v0)
456                 :
457                 : "$1", "$22", "$23", "$24", "$25");
458         return v0;
459 }
460
461 static __inline void
462 alpha_pal_wrunique(u_int64_t tp)
463 {
464         register u_int64_t a0 __asm__("$16") = tp;
465         __asm__ __volatile__("call_pal 0x9f # PAL_wrunique"
466             : "+r" (a0) : : "$1", "$22", "$23", "$24", "$25");
467 }
468  
469 static __inline u_int64_t
470 alpha_pal_rdunique(void)
471 {
472         register u_int64_t v0 __asm__("$0");
473         __asm__ __volatile__("call_pal 0x9e # PAL_rdunique"
474             : "=r" (v0) : : "$1", "$22", "$23", "$24", "$25");
475         return (v0);
476 }
477  
478 static __inline void
479 alpha_pal_tbi(u_int64_t op, u_int64_t va)
480 {
481         register u_int64_t a0 __asm__("$16") = op;
482         register u_int64_t a1 __asm__("$17") = va;
483         __asm__ __volatile__ (
484                 "call_pal 0x33 #PAL_OSF1_tbi"
485                 : "+r" (a0), "+r" (a1)
486                 :
487                 : "$1", "$22", "$23", "$24", "$25");
488 }
489
490 static __inline void
491 alpha_pal_wrent(void *ent, u_int64_t which)
492 {
493         register u_int64_t a0 __asm__("$16") = (u_int64_t) ent;
494         register u_int64_t a1 __asm__("$17") = which;
495         __asm__ __volatile__ (
496                 "call_pal 0x34 #PAL_OSF1_wrent"
497                 : "+r" (a0), "+r" (a1)
498                 :
499                 : "$1", "$22", "$23", "$24", "$25");
500 }
501
502 static __inline u_int64_t
503 alpha_pal_swpipl(u_int64_t newipl)
504 {
505         register u_int64_t a0 __asm__("$16") = newipl;
506         register u_int64_t v0 __asm__("$0");
507         __asm__ __volatile__ (
508                 "call_pal 0x35 #PAL_OSF1_swpipl"
509                 : "=r" (v0), "+r" (a0)
510                 :
511                 : "$1", "$22", "$23", "$24", "$25");
512         return v0;
513 }
514
515 static __inline u_int64_t
516 alpha_pal_rdps(void)
517 {
518         register u_int64_t v0 __asm__("$0");
519         __asm__ __volatile__ (
520                 "call_pal 0x36 #PAL_OSF1_rdps"
521                 : "=r" (v0)
522                 :
523                 : "$1", "$22", "$23", "$24", "$25");
524         return v0;
525 }
526
527 static __inline void
528 alpha_pal_wrusp(u_int64_t usp)
529 {
530         register u_int64_t a0 __asm__("$16") = usp;
531         __asm__ __volatile__ (
532                 "call_pal 0x38 #PAL_wrusp"
533                 : "+r" (a0)
534                 :
535                 : "$1", "$22", "$23", "$24", "$25");
536 }
537
538 static __inline u_int64_t
539 alpha_pal_wrperfmon(u_int64_t arg0, u_int64_t arg1)
540 {
541         register u_int64_t v0 __asm__("$0");
542         register u_int64_t a0 __asm__("$16") = arg0;
543         register u_int64_t a1 __asm__("$17") = arg1;
544         __asm__ __volatile__ (
545                 "call_pal 0x39 #PAL_OSF1_wrperfmon"
546                 : "+r" (a0), "+r" (a1), "=r" (v0)
547                 :
548                 : "$1", "$22", "$23", "$24", "$25");
549         return v0;
550 }
551
552 static __inline u_int64_t
553 alpha_pal_rdusp(void)
554 {
555         register u_int64_t v0 __asm__("$0");
556         __asm__ __volatile__ (
557                 "call_pal 0x3a #PAL_OSF1_rdusp"
558                 : "=r" (v0)
559                 :
560                 : "$1", "$22", "$23", "$24", "$25");
561         return v0;
562 }
563
564 static __inline u_int64_t
565 alpha_pal_whami(void)
566 {
567         register u_int64_t v0 __asm__("$0");
568         __asm__ __volatile__ (
569                 "call_pal 0x3c #PAL_OSF1_whami"
570                 : "=r" (v0)
571                 :
572                 : "$1", "$22", "$23", "$24", "$25");
573         return v0;
574 }
575
576 static __inline void
577 alpha_pal_imb(void)
578 {
579         __asm__ __volatile__ ("call_pal 0x86 #PAL_imb");
580 }
581
582 #endif /* __ALPHA_ALPHA_CPU_H__ */