2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 /* Miscellaneous constants and structures used by the exception
30 #ifndef _PPC_EXCEPTION_H_
31 #define _PPC_EXCEPTION_H_
39 #include <mach/machine/vm_types.h>
40 #include <mach/boolean.h>
41 #include <pexpert/pexpert.h>
42 #include <IOKit/IOInterrupts.h>
43 #include <ppc/machine_routines.h>
45 /* Per processor CPU features */
47 unsigned int Available
;
48 #define pfFloat 0x80000000
50 #define pfAltivec 0x40000000
52 #define pfAvJava 0x20000000
54 #define pfSMPcap 0x10000000
56 #define pfCanSleep 0x08000000
58 #define pfCanNap 0x04000000
60 #define pfCanDoze 0x02000000
62 #define pfThermal 0x01000000
64 #define pfThermInt 0x00800000
66 #define pfLClck 0x00001000
68 #define pfWillNap 0x00000800
70 #define pfNoMSRir 0x00000400
72 #define pfL3pdet 0x00000200
74 #define pfL1i 0x00000100
76 #define pfL1d 0x00000080
78 #define pfL1fa 0x00000040
80 #define pfL2 0x00000020
82 #define pfL2fa 0x00000010
84 #define pfL2i 0x00000008
86 #define pfL3 0x00000004
88 #define pfL3fa 0x00000002
90 #define pfValid 0x00000001
92 unsigned short rptdProc
;
93 unsigned short lineSize
;
104 unsigned int pfMSSCR0
;
105 unsigned int pfMSSCR1
;
106 unsigned int pfICTRL
;
107 unsigned int pfLDSTCR
;
108 unsigned int pfLDSTDB
;
109 unsigned int reserved
[7];
112 typedef struct procFeatures procFeatures
;
115 unsigned int maxTemp
; /* Maximum temprature before damage */
116 unsigned int throttleTemp
; /* Temprature at which to throttle down */
117 unsigned int lowTemp
; /* Interrupt when temprature drops below */
118 unsigned int highTemp
; /* Interrupt when temprature exceeds this */
119 unsigned int thrm3val
; /* Value for thrm3 register */
120 unsigned int rsvd
[3]; /* Pad to cache line */
123 typedef struct thrmControl thrmControl
;
125 /* When an exception is taken, this info is accessed via sprg0 */
126 /* We should always have this one on a cache line boundary */
127 struct per_proc_info
{
128 unsigned short cpu_number
;
129 unsigned short cpu_flags
; /* Various low-level flags */
130 vm_offset_t istackptr
;
131 vm_offset_t intstack_top_ss
;
133 vm_offset_t debstackptr
;
134 vm_offset_t debstack_top_ss
;
136 unsigned int tempwork1
; /* Temp work area - monitor use carefully */
137 unsigned int save_exception_type
;
138 unsigned int old_thread
;
140 /* PPC cache line boundary here - 020 */
142 unsigned int active_kloaded
; /* pointer to active_kloaded[CPU_NO] */
143 unsigned int cpu_data
; /* pointer to cpu_data[CPU_NO] */
144 unsigned int need_ast
; /* pointer to need_ast[CPU_NO] */
146 * Note: the following two pairs of words need to stay in order and each pair must
147 * be in the same reservation (line) granule
149 unsigned int FPU_thread
; /* Thread owning the FPU on this cpu.*/
150 unsigned int FPU_vmmCtx
; /* Owing virtual machine context */
151 unsigned int VMX_thread
; /* Thread owning the VMX on this cpu */
152 unsigned int VMX_vmmCtx
; /* Owing virtual machine context */
153 unsigned int active_stacks
; /* pointer to active_stacks[CPU_NO] */
155 /* PPC cache line boundary here - 040 */
156 unsigned int quickfret
; /* Pointer to savearea for exception exit to free */
157 unsigned int Lastpmap
; /* Last user pmap loaded */
158 unsigned int userspace
; /* Last loaded user memory space ID */
159 unsigned int userpmap
; /* User pmap - real address */
160 unsigned int liveVRSave
; /* VRSave assiciated with live vector registers */
161 unsigned int spcFlags
; /* Special thread flags */
162 unsigned int liveFPSCR
; /* FPSCR which is for the live context */
163 unsigned int ppbbTaskEnv
; /* BlueBox Task Environment */
165 /* PPC cache line boundary here - 060 */
166 boolean_t interrupts_enabled
;
167 unsigned int rsrvd064
;
168 IOInterruptHandler interrupt_handler
;
169 void * interrupt_nub
;
170 unsigned int interrupt_source
;
171 void * interrupt_target
;
172 void * interrupt_refCon
;
173 unsigned int savedSave
; /* Savearea saved across sleep - must be 0 at boot */
175 /* PPC cache line boundary here - 080 */
176 unsigned int MPsigpStat
; /* Signal Processor status (interlocked update for this one) */
177 #define MPsigpMsgp 0xC0000000 /* Message pending (busy + pass) */
178 #define MPsigpBusy 0x80000000 /* Processor area busy, i.e., locked */
179 #define MPsigpPass 0x40000000 /* Busy lock passed to receiving processor */
180 #define MPsigpSrc 0x000000FF /* Processor that owns busy, i.e., the ID of */
181 /* whomever set busy. When a busy is passed, */
182 /* this is the requestor of the function. */
183 #define MPsigpFunc 0x0000FF00 /* Current function */
184 #define MPsigpIdle 0x00 /* No function pending */
185 #define MPsigpSigp 0x04 /* Signal a processor */
186 #define SIGPast 0 /* Requests an ast on target processor */
187 #define SIGPcpureq 1 /* Requests CPU specific function */
188 #define SIGPdebug 2 /* Requests a debugger entry */
189 #define SIGPwake 3 /* Wake up a sleeping processor */
190 #define CPRQtemp 0 /* Get temprature of processor */
191 #define CPRQtimebase 1 /* Get timebase of processor */
192 unsigned int MPsigpParm0
; /* SIGP parm 0 */
193 unsigned int MPsigpParm1
; /* SIGP parm 1 */
194 unsigned int MPsigpParm2
; /* SIGP parm 2 */
196 vm_offset_t start_paddr
;
197 unsigned int ruptStamp
[2]; /* Timebase at last interruption */
199 /* PPC cache line boundary here - 0A0 */
200 procFeatures pf
; /* Processor features */
202 /* PPC cache line boundary here - 100 */
203 thrmControl thrm
; /* Thermal controls */
205 /* PPC cache line boundary here - 120 */
206 unsigned int napStamp
[2]; /* Time base when we napped */
207 unsigned int napTotal
[2]; /* Total nap time in ticks */
208 unsigned int numSIGPast
; /* Number of SIGP asts recieved */
209 unsigned int numSIGPcpureq
; /* Number of SIGP cpu requests recieved */
210 unsigned int numSIGPdebug
; /* Number of SIGP debugs recieved */
211 unsigned int numSIGPwake
; /* Number of SIGP wakes recieved */
213 /* PPC cache line boundary here - 140 */
214 unsigned int spcTRc
; /* Special trace count */
215 unsigned int spcTRp
; /* Special trace buffer pointer */
216 unsigned int Uassist
; /* User Assist Word */
217 unsigned int rsrvd14C
[5]; /* Reserved slots */
219 /* PPC cache line boundary here - 160 */
220 time_base_enable_t time_base_enable
;
221 unsigned int rsrvd164
[7]; /* Reserved slots */
223 /* PPC cache line boundary here - 180 */
224 unsigned int rsrvd180
[8]; /* Reserved slots */
226 /* PPC cache line boundary here - 1A0 */
227 unsigned int rsrvd1A0
[8]; /* Reserved slots */
229 /* PPC cache line boundary here - 1C0 */
230 unsigned int rsrvd1C0
[8]; /* Reserved slots */
232 /* PPC cache line boundary here - 1E0 */
233 double emfp0
; /* Copies of floating point registers */
234 double emfp1
; /* Used for emulation purposes */
274 unsigned int emfpscr_pad
;
275 unsigned int emfpscr
;
276 unsigned int empadfp
[6];
279 unsigned int emvr0
[4]; /* Copies of vector registers used both */
280 unsigned int emvr1
[4]; /* for full vector emulation or */
281 unsigned int emvr2
[4]; /* as saveareas while assisting denorms */
282 unsigned int emvr3
[4];
283 unsigned int emvr4
[4];
284 unsigned int emvr5
[4];
285 unsigned int emvr6
[4];
286 unsigned int emvr7
[4];
287 unsigned int emvr8
[4];
288 unsigned int emvr9
[4];
289 unsigned int emvr10
[4];
290 unsigned int emvr11
[4];
291 unsigned int emvr12
[4];
292 unsigned int emvr13
[4];
293 unsigned int emvr14
[4];
294 unsigned int emvr15
[4];
295 unsigned int emvr16
[4];
296 unsigned int emvr17
[4];
297 unsigned int emvr18
[4];
298 unsigned int emvr19
[4];
299 unsigned int emvr20
[4];
300 unsigned int emvr21
[4];
301 unsigned int emvr22
[4];
302 unsigned int emvr23
[4];
303 unsigned int emvr24
[4];
304 unsigned int emvr25
[4];
305 unsigned int emvr26
[4];
306 unsigned int emvr27
[4];
307 unsigned int emvr28
[4];
308 unsigned int emvr29
[4];
309 unsigned int emvr30
[4];
310 unsigned int emvr31
[4];
311 unsigned int emvscr
[4];
312 unsigned int empadvr
[4];
315 unsigned int patcharea
[56];
321 extern struct per_proc_info per_proc_info
[NCPUS
];
323 typedef struct savearea
{
325 /* The following area corresponds to ppc_saved_state and ppc_thread_state */
328 unsigned int save_srr0
;
329 unsigned int save_srr1
;
330 unsigned int save_r0
;
331 unsigned int save_r1
;
332 unsigned int save_r2
;
333 unsigned int save_r3
;
334 unsigned int save_r4
;
335 unsigned int save_r5
;
337 unsigned int save_r6
;
338 unsigned int save_r7
;
339 unsigned int save_r8
;
340 unsigned int save_r9
;
341 unsigned int save_r10
;
342 unsigned int save_r11
;
343 unsigned int save_r12
;
344 unsigned int save_r13
;
346 unsigned int save_r14
;
347 unsigned int save_r15
;
348 unsigned int save_r16
;
349 unsigned int save_r17
;
350 unsigned int save_r18
;
351 unsigned int save_r19
;
352 unsigned int save_r20
;
353 unsigned int save_r21
;
355 unsigned int save_r22
;
356 unsigned int save_r23
;
357 unsigned int save_r24
;
358 unsigned int save_r25
;
359 unsigned int save_r26
;
360 unsigned int save_r27
;
361 unsigned int save_r28
;
362 unsigned int save_r29
;
364 unsigned int save_r30
;
365 unsigned int save_r31
;
366 unsigned int save_cr
;
367 unsigned int save_xer
;
368 unsigned int save_lr
;
369 unsigned int save_ctr
;
370 unsigned int save_mq
;
371 unsigned int save_vrsave
;
373 unsigned int save_sr_copyin
;
374 unsigned int save_space
;
375 unsigned int save_xfpscrpad
;
376 unsigned int save_xfpscr
;
377 unsigned int save_pad2
[4];
380 /* The following corresponds to ppc_exception_state */
383 unsigned int save_dar
;
384 unsigned int save_dsisr
;
385 unsigned int save_exception
;
386 unsigned int save_pad3
[5];
388 /* The following corresponds to ppc_float_state */
431 unsigned int save_fpscr_pad
;
432 unsigned int save_fpscr
;
433 unsigned int save_pad4
[6];
435 /* The following is the save area for the VMX registers */
438 unsigned int save_vr0
[4];
439 unsigned int save_vr1
[4];
440 unsigned int save_vr2
[4];
441 unsigned int save_vr3
[4];
442 unsigned int save_vr4
[4];
443 unsigned int save_vr5
[4];
444 unsigned int save_vr6
[4];
445 unsigned int save_vr7
[4];
446 unsigned int save_vr8
[4];
447 unsigned int save_vr9
[4];
448 unsigned int save_vr10
[4];
449 unsigned int save_vr11
[4];
450 unsigned int save_vr12
[4];
451 unsigned int save_vr13
[4];
452 unsigned int save_vr14
[4];
453 unsigned int save_vr15
[4];
454 unsigned int save_vr16
[4];
455 unsigned int save_vr17
[4];
456 unsigned int save_vr18
[4];
457 unsigned int save_vr19
[4];
458 unsigned int save_vr20
[4];
459 unsigned int save_vr21
[4];
460 unsigned int save_vr22
[4];
461 unsigned int save_vr23
[4];
462 unsigned int save_vr24
[4];
463 unsigned int save_vr25
[4];
464 unsigned int save_vr26
[4];
465 unsigned int save_vr27
[4];
466 unsigned int save_vr28
[4];
467 unsigned int save_vr29
[4];
468 unsigned int save_vr30
[4];
469 unsigned int save_vr31
[4];
470 unsigned int save_vscr
[4]; /* Note that this is always valid if VMX has been used */
471 unsigned int save_pad5
[4]; /* Insures that vrvalid is on a cache line */
472 unsigned int save_vrvalid
; /* VRs that have been saved */
473 unsigned int save_pad6
[7];
475 /* The following is the save area for the segment registers */
479 unsigned int save_sr0
;
480 unsigned int save_sr1
;
481 unsigned int save_sr2
;
482 unsigned int save_sr3
;
483 unsigned int save_sr4
;
484 unsigned int save_sr5
;
485 unsigned int save_sr6
;
486 unsigned int save_sr7
;
488 unsigned int save_sr8
;
489 unsigned int save_sr9
;
490 unsigned int save_sr10
;
491 unsigned int save_sr11
;
492 unsigned int save_sr12
;
493 unsigned int save_sr13
;
494 unsigned int save_sr14
;
495 unsigned int save_sr15
;
497 /* The following are the control area for this save area */
501 struct savearea
*save_prev
; /* The address of the previous normal savearea */
502 struct savearea
*save_prev_float
; /* The address of the previous floating point savearea */
503 struct savearea
*save_prev_vector
; /* The address of the previous vector savearea */
504 struct savearea
*save_qfret
; /* The "quick release" chain */
505 struct savearea
*save_phys
; /* The physical address of this savearea */
506 struct thread_activation
*save_act
; /* Pointer to the associated activation */
507 unsigned int save_flags
; /* Various flags */
508 #define save_perm 0x80000000 /* Permanent area, cannot be released */
509 unsigned int save_level_fp
; /* Level that floating point state belongs to */
510 unsigned int save_level_vec
; /* Level that vector state belongs to */
514 typedef struct savectl
{ /* Savearea control */
516 unsigned int *sac_next
; /* Points to next savearea page that has a free slot - real */
517 unsigned int sac_vrswap
; /* XOR mask to swap V to R or vice versa */
518 unsigned int sac_alloc
; /* Bitmap of allocated slots */
519 unsigned int sac_flags
; /* Various flags */
523 unsigned int savelock
; /* Lock word for savearea manipulation */
524 int savecount
; /* The total number of save areas allocated */
525 int saveinuse
; /* Number of areas in use */
526 int savemin
; /* We abend if lower than this */
527 int saveneghyst
; /* The negative hysteresis value */
528 int savetarget
; /* The target point for free save areas */
529 int saveposhyst
; /* The positive hysteresis value */
530 unsigned int savefree
; /* Anchor for the freelist queue */
531 /* Cache line (32-byte) boundary */
532 int savextnd
; /* Free list extention count */
533 int saveneed
; /* Number of savearea's needed. So far, we assume we need 3 per activation */
535 int savespare
[5]; /* Spare */
539 extern char *trap_type
[];
541 #endif /* ndef ASSEMBLER */
543 #define sac_empty 0xC0000000 /* Mask with all entries empty */
544 #define sac_cnt 2 /* Number of entries per page */
545 #define sac_busy 0x80000000 /* This page is busy - used during initial allocation */
546 #define sac_perm 0x40000000 /* Page permanently assigned */
548 #define SAVattach 0x80000000 /* Savearea is attached to a thread */
549 #define SAVfpuvalid 0x40000000 /* Savearea contains FPU context */
550 #define SAVvmxvalid 0x20000000 /* Savearea contains VMX context */
551 #define SAVinuse 0xE0000000 /* Save area is inuse */
552 #define SAVrststk 0x00010000 /* Indicates that the current stack should be reset to empty */
553 #define SAVsyscall 0x00020000 /* Indicates that the savearea is associated with a syscall */
554 #define SAVredrive 0x00040000 /* Indicates that the low-level fault handler associated */
555 /* with this savearea should be redriven */
558 #define SIGPactive 0x8000
559 #define needSRload 0x4000
560 #define turnEEon 0x2000
561 #define traceBE 0x1000 /* user mode BE tracing in enabled */
562 #define traceBEb 3 /* bit number for traceBE */
563 #define BootDone 0x0100
564 #define SignalReady 0x0200
565 #define loadMSR 0x7FF4
567 #define T_VECTOR_SIZE 4 /* function pointer size */
568 #define InitialSaveMin 4 /* The initial value for the minimum number of saveareas */
569 #define InitialNegHysteresis 5 /* The number off from target before we adjust upwards */
570 #define InitialPosHysteresis 10 /* The number off from target before we adjust downwards */
571 #define InitialSaveTarget 20 /* The number of saveareas for an initial target */
572 #define InitialSaveAreas 20 /* The number of saveareas to allocate at boot */
573 #define InitialSaveBloks (InitialSaveAreas+sac_cnt-1)/sac_cnt /* The number of savearea blocks to allocate at boot */
575 /* Hardware exceptions */
577 #define T_IN_VAIN (0x00 * T_VECTOR_SIZE)
578 #define T_RESET (0x01 * T_VECTOR_SIZE)
579 #define T_MACHINE_CHECK (0x02 * T_VECTOR_SIZE)
580 #define T_DATA_ACCESS (0x03 * T_VECTOR_SIZE)
581 #define T_INSTRUCTION_ACCESS (0x04 * T_VECTOR_SIZE)
582 #define T_INTERRUPT (0x05 * T_VECTOR_SIZE)
583 #define T_ALIGNMENT (0x06 * T_VECTOR_SIZE)
584 #define T_PROGRAM (0x07 * T_VECTOR_SIZE)
585 #define T_FP_UNAVAILABLE (0x08 * T_VECTOR_SIZE)
586 #define T_DECREMENTER (0x09 * T_VECTOR_SIZE)
587 #define T_IO_ERROR (0x0a * T_VECTOR_SIZE)
588 #define T_RESERVED (0x0b * T_VECTOR_SIZE)
589 #define T_SYSTEM_CALL (0x0c * T_VECTOR_SIZE)
590 #define T_TRACE (0x0d * T_VECTOR_SIZE)
591 #define T_FP_ASSIST (0x0e * T_VECTOR_SIZE)
592 #define T_PERF_MON (0x0f * T_VECTOR_SIZE)
593 #define T_VMX (0x10 * T_VECTOR_SIZE)
594 #define T_INVALID_EXCP0 (0x11 * T_VECTOR_SIZE)
595 #define T_INVALID_EXCP1 (0x12 * T_VECTOR_SIZE)
596 #define T_INVALID_EXCP2 (0x13 * T_VECTOR_SIZE)
597 #define T_INSTRUCTION_BKPT (0x14 * T_VECTOR_SIZE)
598 #define T_SYSTEM_MANAGEMENT (0x15 * T_VECTOR_SIZE)
599 #define T_ALTIVEC_ASSIST (0x16 * T_VECTOR_SIZE)
600 #define T_THERMAL (0x17 * T_VECTOR_SIZE)
601 #define T_INVALID_EXCP5 (0x18 * T_VECTOR_SIZE)
602 #define T_INVALID_EXCP6 (0x19 * T_VECTOR_SIZE)
603 #define T_INVALID_EXCP7 (0x1A * T_VECTOR_SIZE)
604 #define T_INVALID_EXCP8 (0x1B * T_VECTOR_SIZE)
605 #define T_INVALID_EXCP9 (0x1C * T_VECTOR_SIZE)
606 #define T_INVALID_EXCP10 (0x1D * T_VECTOR_SIZE)
607 #define T_INVALID_EXCP11 (0x1E * T_VECTOR_SIZE)
608 #define T_INVALID_EXCP12 (0x1F * T_VECTOR_SIZE)
609 #define T_INVALID_EXCP13 (0x20 * T_VECTOR_SIZE)
611 #define T_RUNMODE_TRACE (0x21 * T_VECTOR_SIZE) /* 601 only */
613 #define T_SIGP (0x22 * T_VECTOR_SIZE)
614 #define T_PREEMPT (0x23 * T_VECTOR_SIZE)
615 #define T_CSWITCH (0x24 * T_VECTOR_SIZE)
616 #define T_SHUTDOWN (0x25 * T_VECTOR_SIZE)
617 #define T_CHOKE (0x26 * T_VECTOR_SIZE)
619 #define T_AST (0x100 * T_VECTOR_SIZE)
620 #define T_MAX T_CHOKE /* Maximum exception no */
622 #define EXCEPTION_VECTOR(exception) (exception * 0x100 /T_VECTOR_SIZE )
625 * System choke (failure) codes
630 #define failMapping 2
631 #define failContext 3
633 /* Always must be last - update failNames table in model_dep.c as well */
634 #define failUnknown 4
638 typedef struct resethandler
{
640 vm_offset_t call_paddr
;
641 vm_offset_t arg__paddr
;
644 extern resethandler_t ResetHandler
;
648 #define RESET_HANDLER_NULL 0x0
649 #define RESET_HANDLER_START 0x1
651 #endif /* _PPC_EXCEPTION_H_ */