Optimize memory layout.
[qemu-palcode.git] / pal.S
blobc314bd7b32bf3af4e2a60c32f2d7b366646d4d07
1 /* QEMU Emulation PALcode.
3    Copyright (C) 2011 Richard Henderson
5    This file is part of QEMU PALcode.
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License or
10    (at your option) any later version.
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the text
15    of the GNU General Public License for more details.
17    You should have received a copy of the GNU General Public License
18    along with this program; see the file COPYING.  If not see
19    <http://www.gnu.org/licenses/>.  */
21         .set            noat
22         .set            nomacro
23         .text
25 #include "pal.h"
26 #include "osf.h"
27 #include SYSTEM_H
30  * Create a standard kernel entry stack frame.
31  */
33 .macro  STACK_FRAME save_ps, save_pc, temp, do_ps
34         // Test if we're currently in user mode
35         and     \save_ps, PS_M_CM, \temp
36         beq     \temp, 0f
37         // Switch to kernel mode
38 .ifne \do_ps
39         mtpr    $31, qemu_ps
40 .endif
41         mtpr    $sp, qemu_usp
42         mfpr    $sp, ptKsp
43         // Allocate the stack frame
44 0:      lda     $sp, -FRM_K_SIZE($sp)
45         stq     \save_ps, FRM_Q_PS($sp)
46         stq     \save_pc, FRM_Q_PC($sp)
47         stq     $gp, FRM_Q_GP($sp)
48         stq     a0, FRM_Q_A0($sp)
49         stq     a1, FRM_Q_A1($sp)
50         stq     a2, FRM_Q_A2($sp)
51 .endm
54  * Allocate a 1 page stack for use by the console.
55  */
56 #define STACK_SIZE      8192
59  * QEMU emulator "hardware" entry points.
60  */
63  * Reset
64  * 
65  * INPUT PARAMETERS:
66  * 
67  *      trap_arg0 = Memory size
68  *      trap_arg1 = Kernel entry (if loaded)
69  */ 
70         .org    0x0000
71         .globl  __start
72 __start:
73         // Initialize GP.
74         br      $gp, .+4
75         ldah    $gp, 0($gp)                     !gpdisp!1
76         lda     $gp, 0($gp)                     !gpdisp!1
77         mtpr    $gp, ptPgp
79         // Disable interrupts; kernel mode
80         lda     t0, IPL_K_HIGH
81         mtpr    t0, qemu_ps
83         // Initialize Stack.
84         SYS_WHAMI a0
85         lda     t0, STACK_SIZE
86         addq    a0, 1, t1
87         mull    t0, t1, t0
88         ldah    t1, stack($gp)                  !gprelhigh
89         lda     t1, stack(t1)                   !gprellow
90         addq    t0, t1, $sp
92         // Do any necessary system setup required for PALmode,
93         // e.g. setting up ptSys[01].
94         bsr     $26, Sys_Setup
96         // Non-boot CPUs can go wait now.
97         bne     a0, 1f
99         // Load boot arguments
100         mfpr    a0, qemu_trap_arg0
101         mfpr    a1, qemu_trap_arg1
102         mfpr    a2, qemu_trap_arg2
104         // Continue in do_start, outside PALmode.
105         ldah    $27, do_start($gp)              !gprelhigh
106         lda     $27, do_start($27)              !gprellow
107         hw_ret  ($27)
109 1:      ldah    $27, do_start_wait($gp)         !gprelhigh
110         lda     $27, do_start_wait($27)         !gprellow
111         hw_ret  ($27)
112 ENDFN   __start
115  * Machine Check
117  * INPUT PARAMETERS:
118  * 
119  *      trap_arg0 = 
120  *      trap_arg1 = 
121  *      trap_arg2 = 
122  */
123         .org    0x0080
124 Pal_Mchk:
125         halt
126 ENDFN   Pal_Mchk
129  * Interprocessor Interrupt
131  * INPUT PARAMETERS:
133  *      trap_arg0 = 
134  *      trap_arg1 =
135  *      trap_arg2 =
137  * The interprocessor interrupt is special, in that PALcode is supposed
138  * to clear the interupt and not wait for the OS to do it.
139  */
140         .org    0x0100
141 Pal_Smp_Interrupt:
142         mfpr    p6, qemu_exc_addr
144         SYS_ACK_SMP p0, p1, p2
146         mfpr    p0, qemu_ps
148         STACK_FRAME p0, p6, p2, 0
150         mov     IPL_K_IP, p0            // Raise IPL
151         mtpr    p0, qemu_ps
153         mfpr    p6, ptEntInt
154         mfpr    $gp, ptKgp
155         lda     a0, INT_K_IP
156         lda     a1, 0
157         lda     a2, 0
159         hw_ret  (p6)
160 ENDFN   Pal_Smp_Interrupt
163  * Clock Interrupt
165  * INPUT PARAMETERS:
167  *      trap_arg0 = 
168  *      trap_arg1 =
169  *      trap_arg2 =
171  * The clock interrupt is special, in that PALcode is supposed
172  * to clear the interupt and not wait for the OS to do it.
173  */
174         .org    0x0180
175 Pal_Clk_Interrupt:
176         mfpr    p6, qemu_exc_addr
178         SYS_ACK_CLK p0, p1, p2
180         mfpr    p0, qemu_ps
182         STACK_FRAME p0, p6, p2, 0
184         mov     IPL_K_CLK, p0           // Raise IPL
185         mtpr    p0, qemu_ps
187         mfpr    p6, ptEntInt
188         mfpr    $gp, ptKgp
189         lda     a0, INT_K_CLK
190         lda     a1, 0
191         lda     a2, 0
193 9:      hw_ret  (p6)
194 ENDFN   Pal_Clk_Interrupt
197  * Device Interrupt
199  * INPUT PARAMETERS:
201  *      trap_arg0 = 
202  *      trap_arg1 =
203  *      trap_arg2 =
204  */ 
205         .org    0x0200
206 Pal_Dev_Interrupt:
207         mfpr    p6, qemu_exc_addr
208         mfpr    p0, qemu_ps
210         STACK_FRAME p0, p6, p2, 0
212         mov     IPL_K_DEV1, p0          // Raise IPL
213         mtpr    p0, qemu_ps
215         bsr     p7, Sys_Dev_Vector
217         mfpr    p7, ptEntInt
218         mfpr    $gp, ptKgp
219         lda     a0, INT_K_DEV
220         lda     a2, 0
221         hw_ret  (p7)
222 ENDFN   Pal_Dev_Interrupt
225  * Memory Fault
227  * INPUT PARAMETERS:
229  *      trap_arg0 = faulting address
230  *      trap_arg1 = fault type (TNV, ACV, FOR, FOW, FOE)
231  *      trap_arg2 = access type (exec=-1, read=0, write=1)
232  */ 
233         .org    0x0280
234 Pal_MMFault:
235         mfpr    p0, qemu_ps
236         mfpr    p6, qemu_exc_addr
237         blbs    p6, MchkBugCheck
239         STACK_FRAME p0, p6, p2, 1
241         mfpr    p0, ptEntMM
242         mfpr    $gp, ptKgp
243         mfpr    a0, qemu_trap_arg0
244         mfpr    a1, qemu_trap_arg1
245         mfpr    a2, qemu_trap_arg2
246         hw_ret  (p0)
247 ENDFN   Pal_MMFault
250  * Unaligned Data
251  * 
252  * INPUT PARAMETERS:
254  *      trap_arg0 = faulting address
255  *      trap_arg1 = opcode of faulting insn
256  *      trap_arg2 = src/dst register number
257  */ 
258         .org    0x0300
259 Pal_Unalign:
260         mfpr    p0, qemu_ps
261         mfpr    p6, qemu_exc_addr
262         addq    p6, 4, p1               // increment past the faulting insn
263         blbs    p6, MchkBugCheck
265         STACK_FRAME p0, p1, p2, 1
267         mfpr    p0, ptEntUna
268         mfpr    $gp, ptKgp
269         mfpr    a0, qemu_trap_arg0
270         mfpr    a1, qemu_trap_arg1
271         mfpr    a2, qemu_trap_arg2
272         hw_ret  (p0)
273 ENDFN   Pal_Unalign
276  * Illegal Opcode
278  * INPUT PARAMETERS:
280  *      trap_arg0 = UNDEFINED
281  *      trap_arg1 = UNDEFINED
282  *      trap_arg2 = UNDEFINED
284  * OUTPUT PARAMETERS:
286  *      r16 (a0) = Instruction fault code
287  *      r17 (a1) = UNPREDICTABLE
288  *      r18 (a2) = UNPREDICTABLE
289  */ 
290         .org    0x0380
291 Pal_OpcDec:
292         mfpr    p0, qemu_ps
293         mfpr    p6, qemu_exc_addr
294         addq    p6, 4, p1               // increment past the faulting insn
295         blbs    p6, MchkBugCheck
297         STACK_FRAME p0, p1, p2, 1
299         mfpr    p0, ptEntIF
300         mfpr    $gp, ptKgp
301         mov     IF_K_OPCDEC, a0
302         hw_ret  (p0)
303 ENDFN   Pal_OpcDec
306  * Arithmetic Trap
308  * INPUT PARAMETERS:
310  *      trap_arg0 = exception type
311  *      trap_arg1 = register modification mask
312  *      trap_arg2 = UNDEFINED
313  */
314         .org    0x0400
315 Pal_Arith:
316         mfpr    p0, qemu_ps
317         mfpr    p6, qemu_exc_addr
318         blbs    p6, MchkBugCheck
320         STACK_FRAME p0, p6, p2, 1
322         mfpr    p0, ptEntArith
323         mfpr    $gp, ptKgp
324         mfpr    a0, qemu_trap_arg0
325         mfpr    a1, qemu_trap_arg1
326         hw_ret  (p0)
327 ENDFN   Pal_Arith
330  * Floating Point Disabled
332  * INPUT PARAMETERS:
334  *      trap_arg0 = UNDEFINED
335  *      trap_arg1 = UNDEFINED
336  *      trap_arg2 = UNDEFINED
338  * OUTPUT PARAMETERS:
340  *      r16 (a0) = Instruction fault code
341  *      r17 (a1) = UNPREDICTABLE
342  *      r18 (a2) = UNPREDICTABLE
343  */ 
344         .org    0x0480
345 Pal_Fen:
346         mfpr    p0, qemu_ps
347         mfpr    p6, qemu_exc_addr
348         blbs    p6, MchkBugCheck
350         STACK_FRAME p0, p6, p2, 1
352         mfpr    p0, ptEntIF
353         mfpr    $gp, ptKgp
354         mov     IF_K_FEN, a0
355         hw_ret  (p0)
356 ENDFN   Pal_Fen
359  * OSF/1 Privileged CALL_PAL Entry Points
360  */
362 #define ORG_CALL_PAL_PRIV(X)    .org    0x1000+64*X
365  * Halt
367  * SIDE EFFECTS:
369  *      We either power down the system or re-enter the console.
370  *      But given that we're not returning to the kernel, there's
371  *      no reason to continue processing in assembler.  Go to C.
372  */
373         ORG_CALL_PAL_PRIV(0x00)
374 CallPal_Halt:
375         bsr     p7, UpdatePCB           // Save kernel data
376         lda     v0, HLT_K_SW_HALT       // FIXME store this somewhere.
378         mtpr    $31, qemu_halt
380         br      Sys_EnterConsole
381 ENDFN   CallPal_Halt
384  * Cache Flush
386  * For QEMU, this is of course a no-op.
387  */
388         ORG_CALL_PAL_PRIV(0x01)
389 CallPal_Cflush:
390         hw_rei
391 ENDFN   CallPal_Cflush
394  * Drain Aborts
396  * For QEMU, this is of course a no-op.
397  */
398         ORG_CALL_PAL_PRIV(0x02)
399 CallPal_Draina:
400         hw_rei
401 ENDFN   CallPal_Draina
403         ORG_CALL_PAL_PRIV(0x03)
404 CallPal_OpcDec03:
405         br      CallPal_OpcDec
406 ENDFN   CallPal_OpcDec03
408         ORG_CALL_PAL_PRIV(0x04)
409 CallPal_OpcDec04:
410         br      CallPal_OpcDec
411 ENDFN   CallPal_OpcDec04
413         ORG_CALL_PAL_PRIV(0x05)
414 CallPal_OpcDec05:
415         br      CallPal_OpcDec
416 ENDFN   CallPal_OpcDec05
418         ORG_CALL_PAL_PRIV(0x06)
419 CallPal_OpcDec06:
420         br      CallPal_OpcDec
421 ENDFN   CallPal_OpcDec06
423         ORG_CALL_PAL_PRIV(0x07)
424 CallPal_OpcDec07:
425         br      CallPal_OpcDec
426 ENDFN   CallPal_OpcDec07
428         ORG_CALL_PAL_PRIV(0x08)
429 CallPal_OpcDec08:
430         br      CallPal_OpcDec
431 ENDFN   CallPal_OpcDec08
434  * Console Service
435  * 
436  * INPUT PARAMETERS:
437  * 
438  *      r16 (a0)          = Option selector
439  *      r17..r21 (a1..a5) = Implementation specific entry parameters
441  * SIDE EFFECTS:
443  *      Registers a0..a5, and v0 are UNPREDICTABLE upon return.
444  */ 
445         ORG_CALL_PAL_PRIV(0x09)
446 CallPal_Cserve:
447         // Most of the entries are densely clustered around 0.
448         mov     0, v0
449         cmpule  a0, 6, p0
450         cmovne  p0, a0, v0
451         br      p0, 1f
452 1:      lda     p0, Cserve_Table-1b(p0)
453         s8addq  v0, p0, p0
454         jmp     $31, (p0), 0
455 ENDFN   CallPal_Cserve
457         .text   1
458         .align  3
459 /* Note that the entries in the following table are all 2 insns.
460    The first entry is unused, and is also where all out-of-range
461    commands are vectored.  */
462 Cserve_Table:
463         br      CallPal_Cserve_Cont
464         nop
465 Cserve_Ldqp:
466         ldq_p   v0, 0(a1)
467         hw_rei
468 ENDFN   Cserve_Ldqp
469 Cserve_Stqp:
470         stq_p   a2, 0(a1)
471         hw_rei
472 ENDFN   Cserve_Stqp
473 Cserve_Get_Wall_Time:
474         mfpr    v0, qemu_walltime
475         hw_rei
476 ENDFN   Cserve_Get_Wall_Time
477 Cserve_Get_Alarm:
478         mfpr    v0, qemu_alarm
479         hw_rei
480 ENDFN   Cserve_Get_Alarm
481 Cserve_Set_Alarm_Rel:
482         // Cheating here: create the absolute time and fall thru.
483         mfpr    p0, qemu_walltime
484         addq    p0, a1, a1
485 ENDFN   Cserve_Set_Alarm_Rel
486 Cserve_Set_Alarm_Abs:
487         mtpr    a1, qemu_alarm
488         hw_rei
489 ENDFN   Cserve_Set_Alarm_Abs
491 CallPal_Cserve_Cont:
492         // ??? For SRM compatibility and their use within Linux, use 52/53
493         // for these.  Anyone know what other "standard" SRM Cserve entry
494         // points are?  Certainly we don't want to be compatible with MILO,
495         // which puts the selector at A2.
496         cmpeq   a0, 52, v0
497         bne     v0, Cserve_Ena
498         cmpeq   a0, 53, v0
499         bne     v0, Cserve_Dis
500         hw_rei
501 ENDFN   CallPal_Cserve_Cont
502         .previous
505  * Swap PALcode
507  * FUNCTIONAL DESCRIPTION:
509  *      The swap PALcode (swppal) function replaces the current 
510  *      (active) PALcode by the specified new PALcode image.  
511  *      This function is intended for use by operating systems 
512  *      only during bootstraps and restarts, or during transitions 
513  *      to console I/O mode.
514  * 
515  *      The PALcode descriptor passed in a0 is interpreted as
516  *      either a PALcode variant or the base physical address
517  *      of the new PALcode image.  If a variant, the PALcode
518  *      image must have been previously loaded.  No PALcode
519  *      loading occurs as a result of this function. 
521  *      NOTE:
522  *      This implementation of SWPPAL does not support PALcode
523  *      variants.  If a variant is specified in a0, a check is
524  *      performed to determine whether the variant is OSF/1 or
525  *      not and the returned status is either unknown variant
526  *      (if not OSF/1) or variant not loaded.
528  * INPUT PARAMETERS:
530  *      r16 (a0) = New PALcode variant or base physical address
531  *      r17 (a1) = New PC
532  *      r18 (a2) = New PCB
533  *      r19 (a3) = New VptPtr
534  * 
535  * OUTPUT PARAMETERS:
537  *      r0 (v0) = Returned status indicating:
538  *                      0 - Success (PALcode was switched)
539  *                      1 - Unknown PALcode variant
540  *                      2 - Known PALcode variant, but PALcode not loaded
542  *      r26 (ra) = r27 (pv) = New PC
543  *              Note that this is non-architected, but is relied on by
544  *              the usage of SwpPal within our own console code in order
545  *              to simplify its use within C code.
547  */
548         ORG_CALL_PAL_PRIV(0x0A)
549 CallPal_SwpPal:
550         // Save a copy of the return address in case of machine check.
551         mfpr    p6, qemu_exc_addr
553         // Accept swapping to OSF PALcode.  The side effect here is to
554         // load the other parameters for the kernel.
555         cmpeq   a0, 2, v0
556         bne     v0, CallPal_SwpPal_Cont
558         // Return as an unknown PALcode variant
559         mov     1, v0
560         hw_rei
561 ENDFN   CallPal_SwpPal
563         .text   1
564 CallPal_SwpPal_Cont:
565         rpcc    p0
566         mtpr    a2, ptPcbb
567         mtpr    a3, qemu_vptptr
569         ldq_p   $sp, PCB_Q_KSP(a2)
570         ldq_p   t0, PCB_Q_USP(a2)
571         ldq_p   t1, PCB_Q_PTBR(a2)
572         ldl_p   t2, PCB_L_PCC(a2)
573         ldq_p   t3, PCB_Q_UNIQUE(a2)
574         ldq_p   t4, PCB_Q_FEN(a2)
576         mtpr    t0, qemu_usp
578         sll     t1, VA_S_OFF, t1
579         mtpr    t1, qemu_ptbr
581         subl    t2, p0, t2
582         mtpr    t2, qemu_pcc_ofs
584         mtpr    t3, qemu_unique
586         and     t4, 1, t4
587         mtpr    t4, qemu_fen
589         mtpr    $31, qemu_tbia          // Flush TLB for new PTBR
591         mov     a1, $26
592         mov     a1, $27
593         hw_ret  (a1)
594 ENDFN   CallPal_SwpPal_Cont
595         .previous
597         ORG_CALL_PAL_PRIV(0x0B)
598 CallPal_OpcDec0B:
599         br      CallPal_OpcDec
600 ENDFN   CallPal_OpcDec0B
602         ORG_CALL_PAL_PRIV(0x0C)
603 CallPal_OpcDec0C:
604         br      CallPal_OpcDec
605 ENDFN   CallPal_OpcDec0C
608  * Write Interprocessor Interrupt Request
610  * INPUT PARAMETERS:
612  *      r16 (a0) = target processor number 
613  * 
614  * OUTPUT PARAMETERS:
616  * SIDE EFFECTS:
617  * 
618  */ 
619         ORG_CALL_PAL_PRIV(0x0D)
620 CallPal_WrIpir:
621         // Save a copy of the return address in case of machine check.
622         mfpr    p6, qemu_exc_addr
624         SYS_WRIPIR      a0, p0, p1, p2
626         hw_rei
627 ENDFN   CallPal_WrIpir
629         ORG_CALL_PAL_PRIV(0x0E)
630 CallPal_OpcDec0E:
631         br      CallPal_OpcDec
632 ENDFN   CallPal_OpcDec0E
634         ORG_CALL_PAL_PRIV(0x0F)
635 CallPal_OpcDec0F:
636         br      CallPal_OpcDec
637 ENDFN   CallPal_OpcDec0F
640  * Read Machine Check Error Summary
642  * INPUT PARAMETERS:
643  * 
644  * OUTPUT PARAMETERS:
646  *      r0 (v0) = returned MCES value
647  * 
648  * SIDE EFFECTS:
650  */ 
651         ORG_CALL_PAL_PRIV(0x10)
652 CallPal_RdMces:
653         mfpr    v0, ptMces              // Get current MCES value
654         and     v0, MCES_M_ALL, v0      // Clear all other bits
655         hw_rei
656 ENDFN   CallPal_RdMces
659  * Write Machine Check Error Summary
661  * INPUT PARAMETERS:
662  * 
663  *      r16 (a0) = MCES<DPC> <- a0<3>,  MCES<DSC> <- a0<4>
664  * 
665  * OUTPUT PARAMETERS:
667  * SIDE EFFECTS:
669  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
670  */ 
671         ORG_CALL_PAL_PRIV(0x11)
672 CallPal_WrMces:
673         // Clear MIP, SCE, PCE
674         and     a0, (MCES_M_MIP | MCES_M_SCE | MCES_M_PCE), p0
675         mfpr    p1, ptMces
676         bic     p1, p0, p1
678         // Copy DPC and DSC
679         and     a0, (MCES_M_DPC | MCES_M_DSC), p0
680         bic     p1, (MCES_M_DPC | MCES_M_DSC), p1
681         or      p1, p0, p1
683         mtpr    p1, ptMces
684         hw_rei
685 ENDFN   CallPal_WrMces
687         ORG_CALL_PAL_PRIV(0x12)
688 CallPal_OpcDec12:
689         br      CallPal_OpcDec
690 ENDFN   CallPal_OpcDec12
692         ORG_CALL_PAL_PRIV(0x13)
693 CallPal_OpcDec13:
694         br      CallPal_OpcDec
695 ENDFN   CallPal_OpcDec13
697         ORG_CALL_PAL_PRIV(0x14)
698 CallPal_OpcDec14:
699         br      CallPal_OpcDec
700 ENDFN   CallPal_OpcDec14
702         ORG_CALL_PAL_PRIV(0x15)
703 CallPal_OpcDec15:
704         br      CallPal_OpcDec
705 ENDFN   CallPal_OpcDec15
707         ORG_CALL_PAL_PRIV(0x16)
708 CallPal_OpcDec16:
709         br      CallPal_OpcDec
710 ENDFN   CallPal_OpcDec16
712         ORG_CALL_PAL_PRIV(0x17)
713 CallPal_OpcDec17:
714         br      CallPal_OpcDec
715 ENDFN   CallPal_OpcDec17
717         ORG_CALL_PAL_PRIV(0x18)
718 CallPal_OpcDec18:
719         br      CallPal_OpcDec
720 ENDFN   CallPal_OpcDec18
722         ORG_CALL_PAL_PRIV(0x19)
723 CallPal_OpcDec19:
724         br      CallPal_OpcDec
725 ENDFN   CallPal_OpcDec19
727         ORG_CALL_PAL_PRIV(0x1A)
728 CallPal_OpcDec1A:
729         br      CallPal_OpcDec
730 ENDFN   CallPal_OpcDec1A
732         ORG_CALL_PAL_PRIV(0x1B)
733 CallPal_OpcDec1B:
734         br      CallPal_OpcDec
735 ENDFN   CallPal_OpcDec1B
737         ORG_CALL_PAL_PRIV(0x1C)
738 CallPal_OpcDec1C:
739         br      CallPal_OpcDec
740 ENDFN   CallPal_OpcDec1C
742         ORG_CALL_PAL_PRIV(0x1D)
743 CallPal_OpcDec1D:
744         br      CallPal_OpcDec
745 ENDFN   CallPal_OpcDec1D
747         ORG_CALL_PAL_PRIV(0x1E)
748 CallPal_OpcDec1E:
749         br      CallPal_OpcDec
750 ENDFN   CallPal_OpcDec1E
752         ORG_CALL_PAL_PRIV(0x1F)
753 CallPal_OpcDec1F:
754         br      CallPal_OpcDec
755 ENDFN   CallPal_OpcDec1F
757         ORG_CALL_PAL_PRIV(0x20)
758 CallPal_OpcDec20:
759         br      CallPal_OpcDec
760 ENDFN   CallPal_OpcDec20
762         ORG_CALL_PAL_PRIV(0x21)
763 CallPal_OpcDec21:
764         br      CallPal_OpcDec
765 ENDFN   CallPal_OpcDec21
767         ORG_CALL_PAL_PRIV(0x22)
768 CallPal_OpcDec22:
769         br      CallPal_OpcDec
770 ENDFN   CallPal_OpcDec22
772         ORG_CALL_PAL_PRIV(0x23)
773 CallPal_OpcDec23:
774         br      CallPal_OpcDec
775 ENDFN   CallPal_OpcDec23
777         ORG_CALL_PAL_PRIV(0x24)
778 CallPal_OpcDec24:
779         br      CallPal_OpcDec
780 ENDFN   CallPal_OpcDec24
782         ORG_CALL_PAL_PRIV(0x25)
783 CallPal_OpcDec25:
784         br      CallPal_OpcDec
785 ENDFN   CallPal_OpcDec25
787         ORG_CALL_PAL_PRIV(0x26)
788 CallPal_OpcDec26:
789         br      CallPal_OpcDec
790 ENDFN   CallPal_OpcDec26
792         ORG_CALL_PAL_PRIV(0x27)
793 CallPal_OpcDec27:
794         br      CallPal_OpcDec
795 ENDFN   CallPal_OpcDec27
797         ORG_CALL_PAL_PRIV(0x28)
798 CallPal_OpcDec28:
799         br      CallPal_OpcDec
800 ENDFN   CallPal_OpcDec28
802         ORG_CALL_PAL_PRIV(0x29)
803 CallPal_OpcDec29:
804         br      CallPal_OpcDec
805 ENDFN   CallPal_OpcDec29
807         ORG_CALL_PAL_PRIV(0x2A)
808 CallPal_OpcDec2A:
809         br      CallPal_OpcDec
810 ENDFN   CallPal_OpcDec2A
813  * Write Floating Point Enable
815  * INPUT PARAMETERS:
816  * 
817  *      r16 (a0) = ICSR<FPE> <- a0<0>
818  * 
819  * SIDE EFFECTS:
821  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
822  */ 
823         ORG_CALL_PAL_PRIV(0x2B)
824 CallPal_WrFen:
825         mfpr    p0, ptPcbb              // Get PCBB
826         and     a0, 1, a0               // Clean new FEN value to single bit
827         mtpr    a0, qemu_fen
828         stl_p   a0, PCB_Q_FEN(p0)       // Write new PCB<FEN>
829         hw_rei
830 ENDFN   CallPal_WrFen
832         ORG_CALL_PAL_PRIV(0x2C)
833 CallPal_OpcDec2C:
834         br      CallPal_OpcDec
835 ENDFN   CallPal_OpcDec2C
838  * Write Virtual Page Table Pointer
840  * INPUT PARAMETERS:
842  *      r16 (a0) = New virtual page table pointer 
844  * SIDE EFFECTS:
846  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
847  */ 
848         ORG_CALL_PAL_PRIV(0x2D)
849 CallPal_WrVptPtr:
850         mtpr    a0, qemu_vptptr
851         hw_rei
852 ENDFN   CallPal_WrVptPtr
854         ORG_CALL_PAL_PRIV(0x2E)
855 CallPal_OpcDec2E:
856         br      CallPal_OpcDec
857 ENDFN   CallPal_OpcDec2E
859         ORG_CALL_PAL_PRIV(0x2F)
860 CallPal_OpcDec2F:
861         br      CallPal_OpcDec
862 ENDFN   CallPal_OpcDec2F
865  * Swap Process Context
867  * FUNCTIONAL DESCRIPTION:
869  *      The swap process context (swpctx) function saves 
870  *      the current process data in the current PCB, then 
871  *      switches to the PCB passed in a0 and loads the
872  *      new process context.  The old PCB is returned in v0.    
873  * 
874  * INPUT PARAMETERS:
875  * 
876  *      r16 (a0) = New PCBB 
877  * 
878  * OUTPUT PARAMETERS:
880  *      r0  (v0) = Old PCBB
881  * 
882  * SIDE EFFECTS:
884  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
885  */ 
886         ORG_CALL_PAL_PRIV(0x30)
887 CallPal_SwpCtx:
888         rpcc    p5                      // Get cycle counter
889         mfpr    p6, qemu_exc_addr       // Save exc_addr for machine check
891         mfpr    v0, ptPcbb              // Get current PCBB
892         mtpr    a0, ptPcbb              // Save new PCBB
893         srl     p5, 32, p7              // Move CC<OFFSET> to low longword
895         addl    p5, p7, p7              // Accumulate time for old pcb
896         stl_p   p7, PCB_L_PCC(v0)
898         ldl_p   t9, PCB_L_PCC(a0)       // Get new PCC
899         subl    t9, p5, p5              // Generate and ...
900         mtpr    p5, qemu_pcc_ofs        // .. set new CC<OFFSET> bits
902         stq_p   $sp, PCB_Q_KSP(v0)      // Store old kernel stack pointer
903         mfpr    t10, qemu_usp           // Save old user stack pointer
904         stq_p   t10, PCB_Q_USP(v0)
906         br      CallPal_SwpCtx_Cont
907 ENDFN   CallPal_SwpCtx
909         .text   1
910 CallPal_SwpCtx_Cont:
911         ldq_p   $sp, PCB_Q_KSP(a0)      // Install new stack pointers
912         ldq_p   t10, PCB_Q_USP(a0)
913         mtpr    t10, qemu_usp
915         mfpr    t10, qemu_unique        // Save old unique value
916         stq_p   t10, PCB_Q_UNIQUE(v0)
917         ldq_p   t10, PCB_Q_UNIQUE(a0)   // Install new unique value
918         mtpr    t10, qemu_unique
920         ldq_p   t8, PCB_Q_FEN(a0)       // Install new FEN
921         and     t8, 1, t8
922         mtpr    t8, qemu_fen
924         // QEMU does not implement an ASN; skip that.
926         ldq_p   t10, PCB_Q_PTBR(a0)     // Install new page tables
927         sll     t10, VA_S_OFF, t10
928         mtpr    t10, qemu_ptbr
929         mtpr    $31, qemu_tbia          // Flush TLB, since we don't do ASNs
931         hw_rei
932 ENDFN   CallPal_SwpCtx_Cont
933         .previous
936  * Write System Value
938  * INPUT PARAMETERS:
940  *      r16 (a0) = New system value 
941  * 
942  * SIDE EFFECTS:
944  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
945  */ 
946         ORG_CALL_PAL_PRIV(0x31)
947 CallPal_WrVal:
948         mtpr    a0, qemu_sysval
949         hw_rei
950 ENDFN   CallPal_WrVal
953  * Read System Value
955  * OUTPUT PARAMETERS:
957  *      r0 (v0) = Returned system value
958  * 
959  * SIDE EFFECTS:
961  *      Registers t0 and t8..t11 are UNPREDICTABLE upon return.
962  */ 
963         ORG_CALL_PAL_PRIV(0x32)
964 CallPal_RdVal:
965         mfpr    v0, qemu_sysval
966         hw_rei
967 ENDFN   CallPal_RdVal
970  * Translation Buffer Invalidate
971  * 
972  * INPUT PARAMETERS:
973  * 
974  *      r16 (a0) = tbi selector type:
976  *              -2 - Flush all TB entries (tbia)
977  *              -1 - Invalidate all TB entries with ASM=0 (tbiap)
978  *               1 - Invalidate ITB entry for va=a1 (tbisi)
979  *               2 - Invalidate DTB entry for va=a1 (tbisd)
980  *               3 - Invalidate both ITB and DTB entry for va=a1 (tbis)
982  *      r17 (a1) = VA for TBISx types
984  * Qemu does not implement ASNs or split I/D tlbs.  Therefore these
985  * collapse to tbia and tbis.
986  * 
987  * SIDE EFFECTS:
989  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
990  */ 
991         ORG_CALL_PAL_PRIV(0x33)
992 CallPal_Tbi:
993         bge     a0, 1f
995         mtpr    $31, qemu_tbia
996         hw_rei
998 1:      mtpr    a1, qemu_tbis
999         hw_rei
1000 ENDFN   CallPal_Tbi
1003  * Write System Entry Address
1005  * INPUT PARAMETERS:
1007  *      r16 (a0) = VA of system entry point
1008  *      r17 (a1) = System entry point selector 
1009  * 
1010  * SIDE EFFECTS:
1012  *      Registers t0, t8..t11, and a0..a1 are UNPREDICTABLE
1013  *      upon return.
1014  */ 
1015         ORG_CALL_PAL_PRIV(0x34)
1016 CallPal_WrEnt:
1017         andnot  a0, 3, a0               // Clean PC<1:0>
1019         cmpult  a1, 6, t8               // Bound the input
1020         cmoveq  t8, 6, a1
1022         br      t0, 1f
1023 1:      lda     t0, WrEnt_Table-1b(t0)
1024         s8addq  a1, t0, t0
1025         jmp     $31, (t0), 0
1026 ENDFN   CallPal_WrEnt
1028         .text   1
1029 WrEnt_Table:
1030 0:      mtpr    a0, ptEntInt
1031         hw_rei
1032 1:      mtpr    a0, ptEntArith
1033         hw_rei
1034 2:      mtpr    a0, ptEntMM
1035         hw_rei
1036 3:      mtpr    a0, ptEntIF
1037         hw_rei
1038 4:      mtpr    a0, ptEntUna
1039         hw_rei
1040 5:      mtpr    a0, ptEntSys
1041         hw_rei
1042 6:      nop
1043         hw_rei
1044 ENDFN   WrEnt_Table
1045         .previous
1048  * Swap Interrupt Priority Level
1049  * 
1050  * INPUT PARAMETERS:
1051  * 
1052  *      r16 (a0) = New IPL
1053  * 
1054  * OUTPUT PARAMETERS:
1056  *      r0  (v0) = Old IPL
1057  * 
1058  * SIDE EFFECTS:
1060  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
1061  */ 
1062         ORG_CALL_PAL_PRIV(0x35)
1063 CallPal_SwpIpl:
1064         mfpr    v0, qemu_ps
1065         and     a0, PS_M_IPL, a0
1066         and     v0, PS_M_IPL, v0
1067         mtpr    a0, qemu_ps
1068         hw_rei
1069 ENDFN   CallPal_SwpIpl
1072  * Read Processor Status
1074  * OUTPUT PARAMETERS:
1076  *      r0 (v0) = Current PS
1077  * 
1078  * SIDE EFFECTS:
1080  *      Registers t0, t8..t11 are UNPREDICTABLE upon return.
1081  */ 
1082         ORG_CALL_PAL_PRIV(0x36)
1083 CallPal_RdPs:
1084         mfpr    v0, qemu_ps
1085         hw_rei
1086 ENDFN   CallPal_RdPs
1089  * Write Kernel Global Pointer
1091  * INPUT PARAMETERS:
1092  * 
1093  *      r16 (a0) = New KGP value
1095  * SIDE EFFECTS:
1097  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
1098  */ 
1099         ORG_CALL_PAL_PRIV(0x37)
1100 CallPal_WrKgp:
1101         mtpr    a0, ptKgp
1102         hw_rei
1103 ENDFN   CallPal_WrKgp
1106  * Write User Stack Pointer
1107  * 
1108  * INPUT PARAMETERS:
1109  * 
1110  *      r16 (a0) = New user stack pointer value
1111  * 
1112  * SIDE EFFECTS:
1114  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
1115  */ 
1116         ORG_CALL_PAL_PRIV(0x38)
1117 CallPal_WrUsp:
1118         mtpr    a0, qemu_usp
1119         hw_rei
1120 ENDFN   CallPal_WrUsp
1123  * Write Performance Monitor
1125  * INPUT PARAMETERS:
1126  * 
1127  *      r16 (a0) = New user stack pointer value
1128  * 
1129  * SIDE EFFECTS:
1131  *      Registers t0, t8..t11, and a0 are UNPREDICTABLE upon return.
1132  */
1133         ORG_CALL_PAL_PRIV(0x39)
1134 CallPal_WrPerfMon:
1135         // Not implemented
1136         hw_rei
1137 ENDFN   CallPal_WrPerfMon
1140  * Read User Stack Pointer
1141  * 
1142  * OUTPUT PARAMETERS:
1144  *      r0 (v0) = User stack pointer value
1145  * 
1146  * SIDE EFFECTS:
1148  *      Registers t0, and t8..t11 are UNPREDICTABLE upon return.
1149  */ 
1150         ORG_CALL_PAL_PRIV(0x3A)
1151 CallPal_RdUsp:
1152         mfpr    v0, qemu_usp
1153         hw_rei
1154 ENDFN   CallPal_RdUsp
1156         ORG_CALL_PAL_PRIV(0x3B)
1157 CallPal_OpcDec3B:
1158         br      CallPal_OpcDec
1159 ENDFN   CallPal_OpcDec3B
1162  * Who Am I
1163  * 
1164  * OUTPUT PARAMETERS:
1166  *      r0 (v0) = Current processor number
1167  * 
1168  * SIDE EFFECTS:
1170  *      Registers t0 and t8..t11 are UNPREDICTABLE upon return.
1171  */ 
1172         ORG_CALL_PAL_PRIV(0x3C)
1173 CallPal_Whami:
1174         SYS_WHAMI v0
1175         hw_rei
1176 ENDFN   CallPal_Whami
1179  * Return From System Call
1181  * INPUT PARAMETERS:
1182  * 
1183  *      r30 (sp) = Pointer to the top of the kernel stack
1184  * 
1185  * OUTPUT PARAMETERS:
1187  *      r29 (gp) = Restored user mode global pointer
1188  *      r30 (sp) = User stack pointer
1189  * 
1190  * SIDE EFFECTS:
1192  *      Registers t0 and t8..t11 are UNPREDICTABLE upon return.
1193  */ 
1194         ORG_CALL_PAL_PRIV(0x3D)
1195 CallPal_RetSys:
1196         ldq     t9, FRM_Q_PC($sp)       // Pop the return address
1197         ldq     $gp, FRM_Q_GP($sp)      // Get the user mode global pointer
1198         lda     t8, FRM_K_SIZE($sp)
1199         mtpr    t8, ptKsp
1201         mov     PS_K_USER, t8           // Set new mode to user
1202         mtpr    t8, qemu_ps
1204         mfpr    $sp, qemu_usp           // Get the user stack pointer
1206         andnot  t9, 3, t9               // Clean return PC<1:0>
1207         hw_ret  (t9)
1208 ENDFN   CallPal_RetSys
1211  * Wait For Interrupt
1213  * FUNCTIONAL DESCRIPTION:
1215  *      If possible, wait for the first of either of the following
1216  *      conditions before returning: any interrupt other than a clock
1217  *      tick; or the first clock tick after a specified number of clock
1218  *      ticks have bbeen skipped.
1220  * INPUT PARAMETERS:
1221  * 
1222  *      r16 (a0) = Maximum number of clock ticks to skip
1223  * 
1224  * OUTPUT PARAMETERS:
1226  *      r0 (v0) = Number of clock ticks actually skipped.
1227  */
1228         ORG_CALL_PAL_PRIV(0x3E)
1229 CallPal_WtInt:
1230         mtpr    $31, qemu_wait
1231         mov     0, v0
1232         hw_rei
1233 ENDFN   CallPal_WtInt
1236  * Return From Trap, Fault, or Interrupt
1238  * INPUT PARAMETERS:
1239  * 
1240  *      r30 (sp) = Pointer to the top of the kernel stack
1241  * 
1242  * OUTPUT PARAMETERS:
1244  *      ps       <- (sp+00)
1245  *      pc       <- (sp+08)
1246  *      r29 (gp) <- (sp+16)
1247  *      r16 (a0) <- (sp+24)
1248  *      r17 (a1) <- (sp+32)
1249  *      r18 (a2) <- (sp+40)
1250  */ 
1251         ORG_CALL_PAL_PRIV(0x3F)
1252         .globl  CallPal_Rti
1253 CallPal_Rti:
1254         mfpr    p6, qemu_exc_addr       // Save exc_addr for machine check
1256         ldq     p4, FRM_Q_PS($sp)       // Get the PS
1257         ldq     p5, FRM_Q_PC($sp)       // Get the return PC
1258         ldq     $gp, FRM_Q_GP($sp)      // Get gp
1259         ldq     a0, FRM_Q_A0($sp)       // Get a0
1260         ldq     a1, FRM_Q_A1($sp)       // Get a1
1261         ldq     a2, FRM_Q_A2($sp)       // Get a2
1262         lda     $sp, FRM_K_SIZE($sp)    // Pop the stack
1264         andnot  p5, 3, p5               // Clean return PC<1:0>
1266         and     p4, PS_M_CM, p3
1267         bne     p3, CallPal_Rti_ToUser
1269         and     p4, PS_M_IPL, p4
1270         mtpr    p4, qemu_ps
1271         hw_ret  (p5)
1272 ENDFN   CallPal_Rti
1274         .text   1
1275 CallPal_Rti_ToUser:
1276         mtpr    p3, qemu_ps
1277         mtpr    $sp, ptKsp
1278         mfpr    $sp, qemu_usp
1279         hw_ret  (p5)
1280 ENDFN   CallPal_Rti_ToUser
1281         .previous
1284  * OSF/1 Unprivileged CALL_PAL Entry Points
1285  */
1287 #define ORG_CALL_PAL_UNPRIV(X)  .org    0x2000+64*(X-0x80)
1290  * A helper routine for the unprivaledged kernel entry points, since the
1291  * actual stack frame setup code is just a tad too large to fit inline.
1293  * INPUT PARAMETERS:
1295  *      p5 = ps
1296  *      p6 = exc_addr
1297  *      p7 = return address
1299  * SIDE EFFECTS:
1301  *      p0 is clobbered
1303  */
1304         .text   1
1305 CallPal_Stack_Frame:
1306         // Test if we're currently in user mode
1307         and     p5, PS_M_CM, p0
1308         beq     p0, 0f
1309 CallPal_Stack_Frame_FromUser:
1310         // Switch to kernel mode
1311         mtpr    $31, qemu_ps
1312         mtpr    $sp, qemu_usp
1313         mfpr    $sp, ptKsp
1315         // Allocate the stack frame
1316         lda     $sp, -FRM_K_SIZE($sp)
1317         stq     p5, FRM_Q_PS($sp)
1318         stq     p6, FRM_Q_PC($sp)
1319         stq     $gp, FRM_Q_GP($sp)
1320         stq     a0, FRM_Q_A0($sp)
1321         stq     a1, FRM_Q_A1($sp)
1322         stq     a2, FRM_Q_A2($sp)
1323         ret     $31, (p7), 0
1324 ENDFN   CallPal_Stack_Frame
1325         .previous
1328  * Breakpoint Trap
1330  * OUTPUT PARAMETERS:
1332  *      r16 (a0) = Code for bpt (0)
1333  *      r17 (a1) = UNPREDICTABLE
1334  *      r18 (a2) = UNPREDICTABLE
1335  */ 
1336         ORG_CALL_PAL_UNPRIV(0x80)
1337 CallPal_Bpt:
1338         mfpr    p5, qemu_ps
1339         mfpr    p6, qemu_exc_addr
1340         bsr     p7, CallPal_Stack_Frame
1342         mfpr    p0, ptEntIF
1343         mfpr    $gp, ptKgp
1344         mov     IF_K_BPT, a0
1345         hw_ret  (p0)
1346 ENDFN   CallPal_Bpt
1349  * Bugcheck Trap
1350  * 
1351  * OUTPUT PARAMETERS:
1353  *      r16 (a0) = Code for bugchk (1)
1354  *      r17 (a1) = UNPREDICTABLE
1355  *      r18 (a2) = UNPREDICTABLE
1356  */ 
1357         ORG_CALL_PAL_UNPRIV(0x81)
1358 CallPal_BugChk:
1359         mfpr    p5, qemu_ps
1360         mfpr    p6, qemu_exc_addr
1361         bsr     p7, CallPal_Stack_Frame
1363         mfpr    p0, ptEntIF
1364         mfpr    $gp, ptKgp
1365         mov     IF_K_BUGCHK, a0
1366         hw_ret  (p0)
1367 ENDFN   CallPal_BugChk
1370         ORG_CALL_PAL_UNPRIV(0x82)
1371 CallPal_OpcDec82:
1372         br      CallPal_OpcDec
1373 ENDFN   CallPal_OpcDec82
1376  * System Call
1377  */ 
1378         ORG_CALL_PAL_UNPRIV(0x83)
1379 CallPal_CallSys:
1380         mfpr    p5, qemu_ps
1381         mfpr    p6, qemu_exc_addr
1383         and     p5, PS_M_CM, p0
1384         beq     p0, 0f
1386         bsr     p7, CallPal_Stack_Frame_FromUser
1388         mfpr    p0, ptEntSys
1389         mfpr    $gp, ptKgp
1390         hw_ret  (p0)
1392 0:      subq    p6, 4, p6               // Get PC of CALL_PAL insn
1393         br      MchkOSBugCheck
1394 ENDFN   CallPal_CallSys
1396         ORG_CALL_PAL_UNPRIV(0x84)
1397 CallPal_OpcDec84:
1398         br      CallPal_OpcDec
1399 ENDFN   CallPal_OpcDec84
1401         ORG_CALL_PAL_UNPRIV(0x85)
1402 CallPal_OpcDec85:
1403         br      CallPal_OpcDec
1404 ENDFN   CallPal_OpcDec85
1408  * I-Stream Memory Barrier
1410  * For QEMU, this is of course a no-op.
1411  */ 
1412         ORG_CALL_PAL_UNPRIV(0x86)
1413 CallPal_Imb:
1414         hw_rei
1415 ENDFN   CallPal_Imb
1418         ORG_CALL_PAL_UNPRIV(0x87)
1419 CallPal_OpcDec87:
1420         br      CallPal_OpcDec
1421 ENDFN   CallPal_OpcDec87
1423         ORG_CALL_PAL_UNPRIV(0x88)
1424 CallPal_OpcDec88:
1425         br      CallPal_OpcDec
1426 ENDFN   CallPal_OpcDec88
1428         ORG_CALL_PAL_UNPRIV(0x89)
1429 CallPal_OpcDec89:
1430         br      CallPal_OpcDec
1431 ENDFN   CallPal_OpcDec89
1433         ORG_CALL_PAL_UNPRIV(0x8A)
1434 CallPal_OpcDec8A:
1435         br      CallPal_OpcDec
1436 ENDFN   CallPal_OpcDec8A
1438         ORG_CALL_PAL_UNPRIV(0x8B)
1439 CallPal_OpcDec8B:
1440         br      CallPal_OpcDec
1441 ENDFN   CallPal_OpcDec8B
1443         ORG_CALL_PAL_UNPRIV(0x8C)
1444 CallPal_OpcDec8C:
1445         br      CallPal_OpcDec
1446 ENDFN   CallPal_OpcDec8C
1448         ORG_CALL_PAL_UNPRIV(0x8D)
1449 CallPal_OpcDec8D:
1450         br      CallPal_OpcDec
1451 ENDFN   CallPal_OpcDec8D
1453         ORG_CALL_PAL_UNPRIV(0x8E)
1454 CallPal_OpcDec8E:
1455         br      CallPal_OpcDec
1456 ENDFN   CallPal_OpcDec8E
1458         ORG_CALL_PAL_UNPRIV(0x8F)
1459 CallPal_OpcDec8F:
1460         br      CallPal_OpcDec
1461 ENDFN   CallPal_OpcDec8F
1463         ORG_CALL_PAL_UNPRIV(0x90)
1464 CallPal_OpcDec90:
1465         br      CallPal_OpcDec
1466 ENDFN   CallPal_OpcDec90
1468         ORG_CALL_PAL_UNPRIV(0x91)
1469 CallPal_OpcDec91:
1470         br      CallPal_OpcDec
1471 ENDFN   CallPal_OpcDec91
1473         ORG_CALL_PAL_UNPRIV(0x92)
1474 CallPal_OpcDec92:
1475         br      CallPal_OpcDec
1476 ENDFN   CallPal_OpcDec92
1478         ORG_CALL_PAL_UNPRIV(0x93)
1479 CallPal_OpcDec93:
1480         br      CallPal_OpcDec
1481 ENDFN   CallPal_OpcDec93
1483         ORG_CALL_PAL_UNPRIV(0x94)
1484 CallPal_OpcDec94:
1485         br      CallPal_OpcDec
1486 ENDFN   CallPal_OpcDec94
1488         ORG_CALL_PAL_UNPRIV(0x95)
1489 CallPal_OpcDec95:
1490         br      CallPal_OpcDec
1491 ENDFN   CallPal_OpcDec95
1493         ORG_CALL_PAL_UNPRIV(0x96)
1494 CallPal_OpcDec96:
1495         br      CallPal_OpcDec
1496 ENDFN   CallPal_OpcDec96
1498         ORG_CALL_PAL_UNPRIV(0x97)
1499 CallPal_OpcDec97:
1500         br      CallPal_OpcDec
1501 ENDFN   CallPal_OpcDec97
1503         ORG_CALL_PAL_UNPRIV(0x98)
1504 CallPal_OpcDec98:
1505         br      CallPal_OpcDec
1506 ENDFN   CallPal_OpcDec98
1508         ORG_CALL_PAL_UNPRIV(0x99)
1509 CallPal_OpcDec99:
1510         br      CallPal_OpcDec
1511 ENDFN   CallPal_OpcDec99
1513         ORG_CALL_PAL_UNPRIV(0x9A)
1514 CallPal_OpcDec9A:
1515         br      CallPal_OpcDec
1516 ENDFN   CallPal_OpcDec9A
1518         ORG_CALL_PAL_UNPRIV(0x9B)
1519 CallPal_OpcDec9B:
1520         br      CallPal_OpcDec
1521 ENDFN   CallPal_OpcDec9B
1523         ORG_CALL_PAL_UNPRIV(0x9C)
1524 CallPal_OpcDec9C:
1525         br      CallPal_OpcDec
1526 ENDFN   CallPal_OpcDec9C
1528         ORG_CALL_PAL_UNPRIV(0x9D)
1529 CallPal_OpcDec9D:
1530         br      CallPal_OpcDec
1531 ENDFN   CallPal_OpcDec9D
1534  * Read Unique Value
1535  * 
1536  * OUTPUT PARAMETERS:
1538  *      r0 (v0) = Returned process unique value
1539 */ 
1540         ORG_CALL_PAL_UNPRIV(0x9E)
1541 CallPal_RdUnique:
1542         mfpr    v0, qemu_unique
1543         hw_rei
1544 ENDFN   CallPal_RdUnique
1547  * Write Unique Value
1548  * 
1549  * INPUT PARAMETERS:
1550  * 
1551  *      r16 (a0) = New process unique value
1552  */ 
1553         ORG_CALL_PAL_UNPRIV(0x9F)
1554 CallPal_WrUnique:
1555         mtpr    a0, qemu_unique
1556         hw_rei
1557 ENDFN   CallPal_WrUnique
1559         ORG_CALL_PAL_UNPRIV(0xA0)
1560 CallPal_OpcDecA0:
1561         br      CallPal_OpcDec
1562 ENDFN   CallPal_OpcDecA0
1564         ORG_CALL_PAL_UNPRIV(0xA1)
1565 CallPal_OpcDecA1:
1566         br      CallPal_OpcDec
1567 ENDFN   CallPal_OpcDecA1
1569         ORG_CALL_PAL_UNPRIV(0xA2)
1570 CallPal_OpcDecA2:
1571         br      CallPal_OpcDec
1572 ENDFN   CallPal_OpcDecA2
1574         ORG_CALL_PAL_UNPRIV(0xA3)
1575 CallPal_OpcDecA3:
1576         br      CallPal_OpcDec
1577 ENDFN   CallPal_OpcDecA3
1579         ORG_CALL_PAL_UNPRIV(0xA4)
1580 CallPal_OpcDecA4:
1581         br      CallPal_OpcDec
1582 ENDFN   CallPal_OpcDecA4
1584         ORG_CALL_PAL_UNPRIV(0xA5)
1585 CallPal_OpcDecA5:
1586         br      CallPal_OpcDec
1587 ENDFN   CallPal_OpcDecA5
1589         ORG_CALL_PAL_UNPRIV(0xA6)
1590 CallPal_OpcDecA6:
1591         br      CallPal_OpcDec
1592 ENDFN   CallPal_OpcDecA6
1594         ORG_CALL_PAL_UNPRIV(0xA7)
1595 CallPal_OpcDecA7:
1596         br      CallPal_OpcDec
1597 ENDFN   CallPal_OpcDecA7
1599         ORG_CALL_PAL_UNPRIV(0xA8)
1600 CallPal_OpcDecA8:
1601         br      CallPal_OpcDec
1602 ENDFN   CallPal_OpcDecA8
1604         ORG_CALL_PAL_UNPRIV(0xA9)
1605 CallPal_OpcDecA9:
1606         br      CallPal_OpcDec
1607 ENDFN   CallPal_OpcDecA9
1610  * Generate Trap
1612  * OUTPUT PARAMETERS:
1614  *      r16 (a0) = Code for gentrap (2)
1615  *      r17 (a1) = UNPREDICTABLE
1616  *      r18 (a2) = UNPREDICTABLE
1617  */ 
1618         ORG_CALL_PAL_UNPRIV(0xAA)
1619 CallPal_GenTrap:
1620         mfpr    p5, qemu_ps
1621         mfpr    p6, qemu_exc_addr
1622         bsr     p7, CallPal_Stack_Frame
1624         mfpr    p0, ptEntIF
1625         mfpr    $gp, ptKgp
1626         mov     IF_K_GENTRAP, a0
1627         hw_ret  (p0)
1628 ENDFN   CallPal_GenTrap
1630         ORG_CALL_PAL_UNPRIV(0xAB)
1631 CallPal_OpcDecAB:
1632         br      CallPal_OpcDec
1633 ENDFN   CallPal_OpcDecAB
1635         ORG_CALL_PAL_UNPRIV(0xAC)
1636 CallPal_OpcDecAC:
1637         br      CallPal_OpcDec
1638 ENDFN   CallPal_OpcDecAC
1640         ORG_CALL_PAL_UNPRIV(0xAD)
1641 CallPal_OpcDecAD:
1642         br      CallPal_OpcDec
1643 ENDFN   CallPal_OpcDecAD
1645         ORG_CALL_PAL_UNPRIV(0xAE)
1646 CallPal_OpcDecAE:
1647         br      CallPal_OpcDec
1648 ENDFN   CallPal_OpcDecAE
1650         ORG_CALL_PAL_UNPRIV(0xAF)
1651 CallPal_OpcDecAF:
1652         br      CallPal_OpcDec
1653 ENDFN   CallPal_OpcDecAF
1655         ORG_CALL_PAL_UNPRIV(0xB0)
1656 CallPal_OpcDecB0:
1657         br      CallPal_OpcDec
1658 ENDFN   CallPal_OpcDecB0
1660         ORG_CALL_PAL_UNPRIV(0xB1)
1661 CallPal_OpcDecB1:
1662         br      CallPal_OpcDec
1663 ENDFN   CallPal_OpcDecB1
1665         ORG_CALL_PAL_UNPRIV(0xB2)
1666 CallPal_OpcDecB2:
1667         br      CallPal_OpcDec
1668 ENDFN   CallPal_OpcDecB2
1670         ORG_CALL_PAL_UNPRIV(0xB3)
1671 CallPal_OpcDecB3:
1672         br      CallPal_OpcDec
1673 ENDFN   CallPal_OpcDecB3
1675         ORG_CALL_PAL_UNPRIV(0xB4)
1676 CallPal_OpcDecB4:
1677         br      CallPal_OpcDec
1678 ENDFN   CallPal_OpcDecB4
1680         ORG_CALL_PAL_UNPRIV(0xB5)
1681 CallPal_OpcDecB5:
1682         br      CallPal_OpcDec
1683 ENDFN   CallPal_OpcDecB5
1685         ORG_CALL_PAL_UNPRIV(0xB6)
1686 CallPal_OpcDecB6:
1687         br      CallPal_OpcDec
1688 ENDFN   CallPal_OpcDecB6
1690         ORG_CALL_PAL_UNPRIV(0xB7)
1691 CallPal_OpcDecB7:
1692         br      CallPal_OpcDec
1693 ENDFN   CallPal_OpcDecB7
1695         ORG_CALL_PAL_UNPRIV(0xB8)
1696 CallPal_OpcDecB8:
1697         br      CallPal_OpcDec
1698 ENDFN   CallPal_OpcDecB8
1700         ORG_CALL_PAL_UNPRIV(0xB9)
1701 CallPal_OpcDecB9:
1702         br      CallPal_OpcDec
1703 ENDFN   CallPal_OpcDecB9
1705         ORG_CALL_PAL_UNPRIV(0xBA)
1706 CallPal_OpcDecBA:
1707         br      CallPal_OpcDec
1708 ENDFN   CallPal_OpcDecBA
1710         ORG_CALL_PAL_UNPRIV(0xBB)
1711 CallPal_OpcDecBB:
1712         br      CallPal_OpcDec
1713 ENDFN   CallPal_OpcDecBB
1715         ORG_CALL_PAL_UNPRIV(0xBC)
1716 CallPal_OpcDecBC:
1717         br      CallPal_OpcDec
1718 ENDFN   CallPal_OpcDecBC
1720         ORG_CALL_PAL_UNPRIV(0xBD)
1721 CallPal_OpcDecBD:
1722         br      CallPal_OpcDec
1723 ENDFN   CallPal_OpcDecBD
1725         ORG_CALL_PAL_UNPRIV(0xBE)
1726 CallPal_OpcDecBE:
1727         br      CallPal_OpcDec
1728 ENDFN   CallPal_OpcDecBE
1730         ORG_CALL_PAL_UNPRIV(0xBF)
1731 CallPal_OpcDec:
1732         mfpr    p5, qemu_ps
1733         mfpr    p6, qemu_exc_addr
1734         bsr     p7, CallPal_Stack_Frame
1736         mfpr    p0, ptEntIF
1737         mfpr    $gp, ptKgp
1738         mov     IF_K_OPCDEC, a0
1739         hw_ret  (p0)
1740 ENDFN   CallPal_OpcDec
1742         .org    0x3000
1743         .text   1
1745  * PALcode detected processor machine check handler.
1747  *      The PALcode-detected machine check handler loads a code
1748  *      indicating the type of machine check error, loads 
1749  *      the System Control Block (SCB) vector for the 
1750  *      processor machine check service routine, sets the 
1751  *      Machine-Check-In-Progress (MIP) flag in the Machine
1752  *      Check Error Summary register (MCES), and merges
1753  *      with the common machine check flow.
1755  *      If a second processor machine check error condition 
1756  *      is detected while the MIP flag is set, the processor 
1757  *      is forced into console I/O mode indicating "double 
1758  *      error abort encountered" as the reason for the halt. 
1759  * 
1760  * CALLING SEQUENCE:
1761  * 
1762  *      Called when an internal processor error is detected
1763  *      that cannot be successfully corrected by hardware or
1764  *      PALcode.
1765  * 
1766  * INPUT PARAMETERS:
1768  *      r14 (p6) = Exception address 
1769  * 
1770  * OUTPUT PARAMETERS:
1772  *      ptMchk0         = saved v0
1773  *      ptMchk1         = saved t0
1774  *      ptMchk2         = saved t3
1775  *      ptMchk3         = saved t4
1776  *      ptMchk4         = saved t5
1777  *      ptMchk5         = saved exc_addr
1778  *      ptMisc<47:32>   = MCHK code
1779  *      ptMisc<31:16>   = SCB vector
1780  *      ptMces<MIP>     = Set
1781  * 
1782  * SIDE EFFECTS:
1784  *      r0 (v0), r1 (t0), and r4..r6 (t3..t5) are saved in
1785  *      PAL temporaries and are available for use as scratch
1786  *      registers by the system specific machine check 
1787  *      handler.
1788  */
1790 MchkBugCheck:
1791 MchkOSBugCheck:
1792         halt
1793 ENDFN   MchkBugCheck
1796  * Common Machine Check Handler
1798  * INPUT STATE:
1800  *      ptMchk0         Saved v0
1801  *      ptMchk1         Saved t0
1802  *      ptMchk2         Saved t3
1803  *      ptMchk3         Saved t4
1804  *      ptMchk4         Saved t5
1805  *      ptMchk5         Saved exc_addr
1806  *      ptMisc<47:32>   MCHK code
1807  *      ptMisc<31:16>   SCB vector
1808  *      ptMces<MIP>     Set
1810  * Registers v0, t0, and t3 .. t5 are available for use, in
1811  * addition to the shadow registers.
1812  */
1814 MchkCommon:
1815         halt
1816 ENDFN   MchkCommon
1819  * Build Machine Check Logout Frame
1821  *      This portion of the  machine check handler builds a logout frame
1822  *      in the PAL impure scratch area, builds a stack frame on the kernel
1823  *      stack (already built if there was an interrupt machine check),
1824  *      loads the GP with the KGP, loads the machine check entry 
1825  *      code in a0, loads a platform-specific interrupt vector 
1826  *      (typically the same value as the SCB offset) in a1, loads 
1827  *      the kseg address of the logout area in a2, and dispatches 
1828  *      to the kernel interrupt handler pointed to by the entInt 
1829  *      operating system entry point.
1831  * OUTPUT PARAMETERS:
1832  * 
1833  *      a0 (r16) = Machine check entry type
1834  *      a1 (r17) = Platform-specific interrupt vector
1835  *      a2 (r18) = Pointer to logout area
1836  */
1838 .macro  STORE_IPR       which, offset, base
1839         mfpr    v0, \which
1840         stq_p   v0, \offset(\base)
1841 .endm
1843 MchkLogOut:
1844         halt
1845 ENDFN   MchkLogOut
1847 MchkDouble:
1848         bsr     p7, UpdatePCB
1849         lda     v0, HLT_K_DBL_MCHK
1850         br      Sys_EnterConsole
1851 ENDFN   MchkDouble
1853 MchkFromPal:
1854         bsr     p7, UpdatePCB
1855         lda     v0, HLT_K_MCHK_FROM_PAL
1856         br      Sys_EnterConsole
1857 ENDFN   MchkFromPal
1859 MchkKspInvalid:
1860         bsr     p7, UpdatePCB
1861         lda     v0, HLT_K_KSP_INVAL
1862         br      Sys_EnterConsole
1863 ENDFN   MchkKspInvalid
1866  * Update the current PCB with new SP and CC info.
1868  * INPUT PARAMETERS:
1870  *      p7      = return linkage
1871  */
1873 UpdatePCB:
1874         rpcc    p5
1875         mfpr    p4, ptPcbb
1877         mfpr    p3, qemu_ps             // Check current mode
1878         and     p3, PS_M_CM, p3
1879         beq     p3, 1f
1881         mtpr    $sp, qemu_usp           // Save user stack pointer
1882         stq_p   $sp, PCB_Q_USP(p4)
1883         br      2f
1885 1:      mtpr    $sp, ptKsp              // Save kernel stack pointer
1886         stq_p   $sp, PCB_Q_KSP(p4)
1888 2:      srl     p5, 32, p3              // Merge for new time
1889         addl    p5, p3, p3
1890         stl_p   p3, PCB_L_PCC(p4)       // Store new time
1892         mfpr    p5, qemu_unique         // Save unique
1893         stq_p   p5, PCB_Q_UNIQUE(p4)
1895         ret     $31, (p7), 0
1896 ENDFN   UpdatePCB
1899  * FIXME
1900  */
1901 Sys_EnterConsole:
1902         halt
1905  * Allocate the initial bootup stack.
1906  */
1908         .section .bss.stack
1909         .align 3
1910         .globl  stack
1911         .type   stack,@object
1912         .size   stack,STACK_SIZE
1913 stack:  .skip   STACK_SIZE