|
|
1.1 root 1: /* QEMU Emulation PALcode.
2:
3: Copyright (C) 2011 Richard Henderson
4:
5: This file is part of QEMU PALcode.
6:
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.
11:
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.
16:
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/>. */
20:
21: .set noat
22: .set nomacro
23: .text
24:
25: #include "pal.h"
26: #include "osf.h"
27: #include SYSTEM_H
28:
29: /*
30: * Create a standard kernel entry stack frame.
31: */
32:
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
52:
53: /*
54: * Allocate a 1 page stack for use by the console.
55: */
56: #define STACK_SIZE 8192
57:
58: /*
59: * QEMU emulator "hardware" entry points.
60: */
61:
62: /*
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
78:
79: // Disable interrupts; kernel mode
80: lda t0, IPL_K_HIGH
81: mtpr t0, qemu_ps
82:
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
91:
92: // Do any necessary system setup required for PALmode,
93: // e.g. setting up ptSys[01].
94: bsr $26, Sys_Setup
95:
96: // Non-boot CPUs can go wait now.
97: bne a0, 1f
98:
99: // Load boot arguments
100: mfpr a0, qemu_trap_arg0
101: mfpr a1, qemu_trap_arg1
102: mfpr a2, qemu_trap_arg2
103:
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)
108:
109: 1: ldah $27, do_start_wait($gp) !gprelhigh
110: lda $27, do_start_wait($27) !gprellow
111: hw_ret ($27)
112: ENDFN __start
113:
114: /*
115: * Machine Check
116: *
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
127:
128: /*
129: * Interprocessor Interrupt
130: *
131: * INPUT PARAMETERS:
132: *
133: * trap_arg0 =
134: * trap_arg1 =
135: * trap_arg2 =
136: *
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
143:
144: SYS_ACK_SMP p0, p1, p2
145:
146: mfpr p0, qemu_ps
147:
148: STACK_FRAME p0, p6, p2, 0
149:
150: mov IPL_K_IP, p0 // Raise IPL
151: mtpr p0, qemu_ps
152:
153: mfpr p6, ptEntInt
154: mfpr $gp, ptKgp
155: lda a0, INT_K_IP
156: lda a1, 0
157: lda a2, 0
158:
159: hw_ret (p6)
160: ENDFN Pal_Smp_Interrupt
161:
162: /*
163: * Clock Interrupt
164: *
165: * INPUT PARAMETERS:
166: *
167: * trap_arg0 =
168: * trap_arg1 =
169: * trap_arg2 =
170: *
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
177:
178: SYS_ACK_CLK p0, p1, p2
179:
180: mfpr p0, qemu_ps
181:
182: STACK_FRAME p0, p6, p2, 0
183:
184: mov IPL_K_CLK, p0 // Raise IPL
185: mtpr p0, qemu_ps
186:
187: mfpr p6, ptEntInt
188: mfpr $gp, ptKgp
189: lda a0, INT_K_CLK
190: lda a1, 0
191: lda a2, 0
192:
193: 9: hw_ret (p6)
194: ENDFN Pal_Clk_Interrupt
195:
196: /*
197: * Device Interrupt
198: *
199: * INPUT PARAMETERS:
200: *
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
209:
210: STACK_FRAME p0, p6, p2, 0
211:
212: mov IPL_K_DEV1, p0 // Raise IPL
213: mtpr p0, qemu_ps
214:
215: bsr p7, Sys_Dev_Vector
216:
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
223:
224: /*
225: * Memory Fault
226: *
227: * INPUT PARAMETERS:
228: *
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
238:
239: STACK_FRAME p0, p6, p2, 1
240:
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
248:
249: /*
250: * Unaligned Data
251: *
252: * INPUT PARAMETERS:
253: *
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
264:
265: STACK_FRAME p0, p1, p2, 1
266:
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
274:
275: /*
276: * Illegal Opcode
277: *
278: * INPUT PARAMETERS:
279: *
280: * trap_arg0 = UNDEFINED
281: * trap_arg1 = UNDEFINED
282: * trap_arg2 = UNDEFINED
283: *
284: * OUTPUT PARAMETERS:
285: *
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
296:
297: STACK_FRAME p0, p1, p2, 1
298:
299: mfpr p0, ptEntIF
300: mfpr $gp, ptKgp
301: mov IF_K_OPCDEC, a0
302: hw_ret (p0)
303: ENDFN Pal_OpcDec
304:
305: /*
306: * Arithmetic Trap
307: *
308: * INPUT PARAMETERS:
309: *
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
319:
320: STACK_FRAME p0, p6, p2, 1
321:
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
328:
329: /*
330: * Floating Point Disabled
331: *
332: * INPUT PARAMETERS:
333: *
334: * trap_arg0 = UNDEFINED
335: * trap_arg1 = UNDEFINED
336: * trap_arg2 = UNDEFINED
337: *
338: * OUTPUT PARAMETERS:
339: *
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
349:
350: STACK_FRAME p0, p6, p2, 1
351:
352: mfpr p0, ptEntIF
353: mfpr $gp, ptKgp
354: mov IF_K_FEN, a0
355: hw_ret (p0)
356: ENDFN Pal_Fen
357:
358: /*
359: * OSF/1 Privileged CALL_PAL Entry Points
360: */
361:
362: #define ORG_CALL_PAL_PRIV(X) .org 0x1000+64*X
363:
364: /*
365: * Halt
366: *
367: * SIDE EFFECTS:
368: *
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.
377:
378: mtpr $31, qemu_halt
379:
380: br Sys_EnterConsole
381: ENDFN CallPal_Halt
382:
383: /*
384: * Cache Flush
385: *
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
392:
393: /*
394: * Drain Aborts
395: *
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
402:
403: ORG_CALL_PAL_PRIV(0x03)
404: CallPal_OpcDec03:
405: br CallPal_OpcDec
406: ENDFN CallPal_OpcDec03
407:
408: ORG_CALL_PAL_PRIV(0x04)
409: CallPal_OpcDec04:
410: br CallPal_OpcDec
411: ENDFN CallPal_OpcDec04
412:
413: ORG_CALL_PAL_PRIV(0x05)
414: CallPal_OpcDec05:
415: br CallPal_OpcDec
416: ENDFN CallPal_OpcDec05
417:
418: ORG_CALL_PAL_PRIV(0x06)
419: CallPal_OpcDec06:
420: br CallPal_OpcDec
421: ENDFN CallPal_OpcDec06
422:
423: ORG_CALL_PAL_PRIV(0x07)
424: CallPal_OpcDec07:
425: br CallPal_OpcDec
426: ENDFN CallPal_OpcDec07
427:
428: ORG_CALL_PAL_PRIV(0x08)
429: CallPal_OpcDec08:
430: br CallPal_OpcDec
431: ENDFN CallPal_OpcDec08
432:
433: /*
434: * Console Service
435: *
436: * INPUT PARAMETERS:
437: *
438: * r16 (a0) = Option selector
439: * r17..r21 (a1..a5) = Implementation specific entry parameters
440: *
441: * SIDE EFFECTS:
442: *
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
456:
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
490:
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
503:
504: /*
505: * Swap PALcode
506: *
507: * FUNCTIONAL DESCRIPTION:
508: *
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.
520: *
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.
527: *
528: * INPUT PARAMETERS:
529: *
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:
536: *
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
541: *
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.
546: *
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
552:
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
557:
558: // Return as an unknown PALcode variant
559: mov 1, v0
560: hw_rei
561: ENDFN CallPal_SwpPal
562:
563: .text 1
564: CallPal_SwpPal_Cont:
565: rpcc p0
566: mtpr a2, ptPcbb
567: mtpr a3, qemu_vptptr
568:
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)
575:
576: mtpr t0, qemu_usp
577:
578: sll t1, VA_S_OFF, t1
579: mtpr t1, qemu_ptbr
580:
581: subl t2, p0, t2
582: mtpr t2, qemu_pcc_ofs
583:
584: mtpr t3, qemu_unique
585:
586: and t4, 1, t4
587: mtpr t4, qemu_fen
588:
589: mtpr $31, qemu_tbia // Flush TLB for new PTBR
590:
591: mov a1, $26
592: mov a1, $27
593: hw_ret (a1)
594: ENDFN CallPal_SwpPal_Cont
595: .previous
596:
597: ORG_CALL_PAL_PRIV(0x0B)
598: CallPal_OpcDec0B:
599: br CallPal_OpcDec
600: ENDFN CallPal_OpcDec0B
601:
602: ORG_CALL_PAL_PRIV(0x0C)
603: CallPal_OpcDec0C:
604: br CallPal_OpcDec
605: ENDFN CallPal_OpcDec0C
606:
607: /*
608: * Write Interprocessor Interrupt Request
609: *
610: * INPUT PARAMETERS:
611: *
612: * r16 (a0) = target processor number
613: *
614: * OUTPUT PARAMETERS:
615: *
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
623:
624: SYS_WRIPIR a0, p0, p1, p2
625:
626: hw_rei
627: ENDFN CallPal_WrIpir
628:
629: ORG_CALL_PAL_PRIV(0x0E)
630: CallPal_OpcDec0E:
631: br CallPal_OpcDec
632: ENDFN CallPal_OpcDec0E
633:
634: ORG_CALL_PAL_PRIV(0x0F)
635: CallPal_OpcDec0F:
636: br CallPal_OpcDec
637: ENDFN CallPal_OpcDec0F
638:
639: /*
640: * Read Machine Check Error Summary
641: *
642: * INPUT PARAMETERS:
643: *
644: * OUTPUT PARAMETERS:
645: *
646: * r0 (v0) = returned MCES value
647: *
648: * SIDE EFFECTS:
649: *
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
657:
658: /*
659: * Write Machine Check Error Summary
660: *
661: * INPUT PARAMETERS:
662: *
663: * r16 (a0) = MCES<DPC> <- a0<3>, MCES<DSC> <- a0<4>
664: *
665: * OUTPUT PARAMETERS:
666: *
667: * SIDE EFFECTS:
668: *
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
677:
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
682:
683: mtpr p1, ptMces
684: hw_rei
685: ENDFN CallPal_WrMces
686:
687: ORG_CALL_PAL_PRIV(0x12)
688: CallPal_OpcDec12:
689: br CallPal_OpcDec
690: ENDFN CallPal_OpcDec12
691:
692: ORG_CALL_PAL_PRIV(0x13)
693: CallPal_OpcDec13:
694: br CallPal_OpcDec
695: ENDFN CallPal_OpcDec13
696:
697: ORG_CALL_PAL_PRIV(0x14)
698: CallPal_OpcDec14:
699: br CallPal_OpcDec
700: ENDFN CallPal_OpcDec14
701:
702: ORG_CALL_PAL_PRIV(0x15)
703: CallPal_OpcDec15:
704: br CallPal_OpcDec
705: ENDFN CallPal_OpcDec15
706:
707: ORG_CALL_PAL_PRIV(0x16)
708: CallPal_OpcDec16:
709: br CallPal_OpcDec
710: ENDFN CallPal_OpcDec16
711:
712: ORG_CALL_PAL_PRIV(0x17)
713: CallPal_OpcDec17:
714: br CallPal_OpcDec
715: ENDFN CallPal_OpcDec17
716:
717: ORG_CALL_PAL_PRIV(0x18)
718: CallPal_OpcDec18:
719: br CallPal_OpcDec
720: ENDFN CallPal_OpcDec18
721:
722: ORG_CALL_PAL_PRIV(0x19)
723: CallPal_OpcDec19:
724: br CallPal_OpcDec
725: ENDFN CallPal_OpcDec19
726:
727: ORG_CALL_PAL_PRIV(0x1A)
728: CallPal_OpcDec1A:
729: br CallPal_OpcDec
730: ENDFN CallPal_OpcDec1A
731:
732: ORG_CALL_PAL_PRIV(0x1B)
733: CallPal_OpcDec1B:
734: br CallPal_OpcDec
735: ENDFN CallPal_OpcDec1B
736:
737: ORG_CALL_PAL_PRIV(0x1C)
738: CallPal_OpcDec1C:
739: br CallPal_OpcDec
740: ENDFN CallPal_OpcDec1C
741:
742: ORG_CALL_PAL_PRIV(0x1D)
743: CallPal_OpcDec1D:
744: br CallPal_OpcDec
745: ENDFN CallPal_OpcDec1D
746:
747: ORG_CALL_PAL_PRIV(0x1E)
748: CallPal_OpcDec1E:
749: br CallPal_OpcDec
750: ENDFN CallPal_OpcDec1E
751:
752: ORG_CALL_PAL_PRIV(0x1F)
753: CallPal_OpcDec1F:
754: br CallPal_OpcDec
755: ENDFN CallPal_OpcDec1F
756:
757: ORG_CALL_PAL_PRIV(0x20)
758: CallPal_OpcDec20:
759: br CallPal_OpcDec
760: ENDFN CallPal_OpcDec20
761:
762: ORG_CALL_PAL_PRIV(0x21)
763: CallPal_OpcDec21:
764: br CallPal_OpcDec
765: ENDFN CallPal_OpcDec21
766:
767: ORG_CALL_PAL_PRIV(0x22)
768: CallPal_OpcDec22:
769: br CallPal_OpcDec
770: ENDFN CallPal_OpcDec22
771:
772: ORG_CALL_PAL_PRIV(0x23)
773: CallPal_OpcDec23:
774: br CallPal_OpcDec
775: ENDFN CallPal_OpcDec23
776:
777: ORG_CALL_PAL_PRIV(0x24)
778: CallPal_OpcDec24:
779: br CallPal_OpcDec
780: ENDFN CallPal_OpcDec24
781:
782: ORG_CALL_PAL_PRIV(0x25)
783: CallPal_OpcDec25:
784: br CallPal_OpcDec
785: ENDFN CallPal_OpcDec25
786:
787: ORG_CALL_PAL_PRIV(0x26)
788: CallPal_OpcDec26:
789: br CallPal_OpcDec
790: ENDFN CallPal_OpcDec26
791:
792: ORG_CALL_PAL_PRIV(0x27)
793: CallPal_OpcDec27:
794: br CallPal_OpcDec
795: ENDFN CallPal_OpcDec27
796:
797: ORG_CALL_PAL_PRIV(0x28)
798: CallPal_OpcDec28:
799: br CallPal_OpcDec
800: ENDFN CallPal_OpcDec28
801:
802: ORG_CALL_PAL_PRIV(0x29)
803: CallPal_OpcDec29:
804: br CallPal_OpcDec
805: ENDFN CallPal_OpcDec29
806:
807: ORG_CALL_PAL_PRIV(0x2A)
808: CallPal_OpcDec2A:
809: br CallPal_OpcDec
810: ENDFN CallPal_OpcDec2A
811:
812: /*
813: * Write Floating Point Enable
814: *
815: * INPUT PARAMETERS:
816: *
817: * r16 (a0) = ICSR<FPE> <- a0<0>
818: *
819: * SIDE EFFECTS:
820: *
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
831:
832: ORG_CALL_PAL_PRIV(0x2C)
833: CallPal_OpcDec2C:
834: br CallPal_OpcDec
835: ENDFN CallPal_OpcDec2C
836:
837: /*
838: * Write Virtual Page Table Pointer
839: *
840: * INPUT PARAMETERS:
841: *
842: * r16 (a0) = New virtual page table pointer
843: *
844: * SIDE EFFECTS:
845: *
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
853:
854: ORG_CALL_PAL_PRIV(0x2E)
855: CallPal_OpcDec2E:
856: br CallPal_OpcDec
857: ENDFN CallPal_OpcDec2E
858:
859: ORG_CALL_PAL_PRIV(0x2F)
860: CallPal_OpcDec2F:
861: br CallPal_OpcDec
862: ENDFN CallPal_OpcDec2F
863:
864: /*
865: * Swap Process Context
866: *
867: * FUNCTIONAL DESCRIPTION:
868: *
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:
879: *
880: * r0 (v0) = Old PCBB
881: *
882: * SIDE EFFECTS:
883: *
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
890:
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
894:
895: addl p5, p7, p7 // Accumulate time for old pcb
896: stl_p p7, PCB_L_PCC(v0)
897:
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
901:
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)
905:
906: br CallPal_SwpCtx_Cont
907: ENDFN CallPal_SwpCtx
908:
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
914:
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
919:
920: ldq_p t8, PCB_Q_FEN(a0) // Install new FEN
921: and t8, 1, t8
922: mtpr t8, qemu_fen
923:
924: // QEMU does not implement an ASN; skip that.
925:
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
930:
931: hw_rei
932: ENDFN CallPal_SwpCtx_Cont
933: .previous
934:
935: /*
936: * Write System Value
937: *
938: * INPUT PARAMETERS:
939: *
940: * r16 (a0) = New system value
941: *
942: * SIDE EFFECTS:
943: *
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
951:
952: /*
953: * Read System Value
954: *
955: * OUTPUT PARAMETERS:
956: *
957: * r0 (v0) = Returned system value
958: *
959: * SIDE EFFECTS:
960: *
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
968:
969: /*
970: * Translation Buffer Invalidate
971: *
972: * INPUT PARAMETERS:
973: *
974: * r16 (a0) = tbi selector type:
975: *
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)
981: *
982: * r17 (a1) = VA for TBISx types
983: *
984: * Qemu does not implement ASNs or split I/D tlbs. Therefore these
985: * collapse to tbia and tbis.
986: *
987: * SIDE EFFECTS:
988: *
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
994:
995: mtpr $31, qemu_tbia
996: hw_rei
997:
998: 1: mtpr a1, qemu_tbis
999: hw_rei
1000: ENDFN CallPal_Tbi
1001:
1002: /*
1003: * Write System Entry Address
1004: *
1005: * INPUT PARAMETERS:
1006: *
1007: * r16 (a0) = VA of system entry point
1008: * r17 (a1) = System entry point selector
1009: *
1010: * SIDE EFFECTS:
1011: *
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>
1018:
1019: cmpult a1, 6, t8 // Bound the input
1020: cmoveq t8, 6, a1
1021:
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
1027:
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
1046:
1047: /*
1048: * Swap Interrupt Priority Level
1049: *
1050: * INPUT PARAMETERS:
1051: *
1052: * r16 (a0) = New IPL
1053: *
1054: * OUTPUT PARAMETERS:
1055: *
1056: * r0 (v0) = Old IPL
1057: *
1058: * SIDE EFFECTS:
1059: *
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
1070:
1071: /*
1072: * Read Processor Status
1073: *
1074: * OUTPUT PARAMETERS:
1075: *
1076: * r0 (v0) = Current PS
1077: *
1078: * SIDE EFFECTS:
1079: *
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
1087:
1088: /*
1089: * Write Kernel Global Pointer
1090: *
1091: * INPUT PARAMETERS:
1092: *
1093: * r16 (a0) = New KGP value
1094: *
1095: * SIDE EFFECTS:
1096: *
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
1104:
1105: /*
1106: * Write User Stack Pointer
1107: *
1108: * INPUT PARAMETERS:
1109: *
1110: * r16 (a0) = New user stack pointer value
1111: *
1112: * SIDE EFFECTS:
1113: *
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
1121:
1122: /*
1123: * Write Performance Monitor
1124: *
1125: * INPUT PARAMETERS:
1126: *
1127: * r16 (a0) = New user stack pointer value
1128: *
1129: * SIDE EFFECTS:
1130: *
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
1138:
1139: /*
1140: * Read User Stack Pointer
1141: *
1142: * OUTPUT PARAMETERS:
1143: *
1144: * r0 (v0) = User stack pointer value
1145: *
1146: * SIDE EFFECTS:
1147: *
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
1155:
1156: ORG_CALL_PAL_PRIV(0x3B)
1157: CallPal_OpcDec3B:
1158: br CallPal_OpcDec
1159: ENDFN CallPal_OpcDec3B
1160:
1161: /*
1162: * Who Am I
1163: *
1164: * OUTPUT PARAMETERS:
1165: *
1166: * r0 (v0) = Current processor number
1167: *
1168: * SIDE EFFECTS:
1169: *
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
1177:
1178: /*
1179: * Return From System Call
1180: *
1181: * INPUT PARAMETERS:
1182: *
1183: * r30 (sp) = Pointer to the top of the kernel stack
1184: *
1185: * OUTPUT PARAMETERS:
1186: *
1187: * r29 (gp) = Restored user mode global pointer
1188: * r30 (sp) = User stack pointer
1189: *
1190: * SIDE EFFECTS:
1191: *
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
1200:
1201: mov PS_K_USER, t8 // Set new mode to user
1202: mtpr t8, qemu_ps
1203:
1204: mfpr $sp, qemu_usp // Get the user stack pointer
1205:
1206: andnot t9, 3, t9 // Clean return PC<1:0>
1207: hw_ret (t9)
1208: ENDFN CallPal_RetSys
1209:
1210: /*
1211: * Wait For Interrupt
1212: *
1213: * FUNCTIONAL DESCRIPTION:
1214: *
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.
1219: *
1220: * INPUT PARAMETERS:
1221: *
1222: * r16 (a0) = Maximum number of clock ticks to skip
1223: *
1224: * OUTPUT PARAMETERS:
1225: *
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
1234:
1235: /*
1236: * Return From Trap, Fault, or Interrupt
1237: *
1238: * INPUT PARAMETERS:
1239: *
1240: * r30 (sp) = Pointer to the top of the kernel stack
1241: *
1242: * OUTPUT PARAMETERS:
1243: *
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
1255:
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
1263:
1264: andnot p5, 3, p5 // Clean return PC<1:0>
1265:
1266: and p4, PS_M_CM, p3
1267: bne p3, CallPal_Rti_ToUser
1268:
1269: and p4, PS_M_IPL, p4
1270: mtpr p4, qemu_ps
1271: hw_ret (p5)
1272: ENDFN CallPal_Rti
1273:
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
1282:
1283: /*
1284: * OSF/1 Unprivileged CALL_PAL Entry Points
1285: */
1286:
1287: #define ORG_CALL_PAL_UNPRIV(X) .org 0x2000+64*(X-0x80)
1288:
1289: /*
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.
1292: *
1293: * INPUT PARAMETERS:
1294: *
1295: * p5 = ps
1296: * p6 = exc_addr
1297: * p7 = return address
1298: *
1299: * SIDE EFFECTS:
1300: *
1301: * p0 is clobbered
1302: *
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
1314: 0:
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
1326:
1327: /*
1328: * Breakpoint Trap
1329: *
1330: * OUTPUT PARAMETERS:
1331: *
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
1341:
1342: mfpr p0, ptEntIF
1343: mfpr $gp, ptKgp
1344: mov IF_K_BPT, a0
1345: hw_ret (p0)
1346: ENDFN CallPal_Bpt
1347:
1348: /*
1349: * Bugcheck Trap
1350: *
1351: * OUTPUT PARAMETERS:
1352: *
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
1362:
1363: mfpr p0, ptEntIF
1364: mfpr $gp, ptKgp
1365: mov IF_K_BUGCHK, a0
1366: hw_ret (p0)
1367: ENDFN CallPal_BugChk
1368:
1369:
1370: ORG_CALL_PAL_UNPRIV(0x82)
1371: CallPal_OpcDec82:
1372: br CallPal_OpcDec
1373: ENDFN CallPal_OpcDec82
1374:
1375: /*
1376: * System Call
1377: */
1378: ORG_CALL_PAL_UNPRIV(0x83)
1379: CallPal_CallSys:
1380: mfpr p5, qemu_ps
1381: mfpr p6, qemu_exc_addr
1382:
1383: and p5, PS_M_CM, p0
1384: beq p0, 0f
1385:
1386: bsr p7, CallPal_Stack_Frame_FromUser
1387:
1388: mfpr p0, ptEntSys
1389: mfpr $gp, ptKgp
1390: hw_ret (p0)
1391:
1392: 0: subq p6, 4, p6 // Get PC of CALL_PAL insn
1393: br MchkOSBugCheck
1394: ENDFN CallPal_CallSys
1395:
1396: ORG_CALL_PAL_UNPRIV(0x84)
1397: CallPal_OpcDec84:
1398: br CallPal_OpcDec
1399: ENDFN CallPal_OpcDec84
1400:
1401: ORG_CALL_PAL_UNPRIV(0x85)
1402: CallPal_OpcDec85:
1403: br CallPal_OpcDec
1404: ENDFN CallPal_OpcDec85
1405:
1406:
1407: /*
1408: * I-Stream Memory Barrier
1409: *
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
1416:
1417:
1418: ORG_CALL_PAL_UNPRIV(0x87)
1419: CallPal_OpcDec87:
1420: br CallPal_OpcDec
1421: ENDFN CallPal_OpcDec87
1422:
1423: ORG_CALL_PAL_UNPRIV(0x88)
1424: CallPal_OpcDec88:
1425: br CallPal_OpcDec
1426: ENDFN CallPal_OpcDec88
1427:
1428: ORG_CALL_PAL_UNPRIV(0x89)
1429: CallPal_OpcDec89:
1430: br CallPal_OpcDec
1431: ENDFN CallPal_OpcDec89
1432:
1433: ORG_CALL_PAL_UNPRIV(0x8A)
1434: CallPal_OpcDec8A:
1435: br CallPal_OpcDec
1436: ENDFN CallPal_OpcDec8A
1437:
1438: ORG_CALL_PAL_UNPRIV(0x8B)
1439: CallPal_OpcDec8B:
1440: br CallPal_OpcDec
1441: ENDFN CallPal_OpcDec8B
1442:
1443: ORG_CALL_PAL_UNPRIV(0x8C)
1444: CallPal_OpcDec8C:
1445: br CallPal_OpcDec
1446: ENDFN CallPal_OpcDec8C
1447:
1448: ORG_CALL_PAL_UNPRIV(0x8D)
1449: CallPal_OpcDec8D:
1450: br CallPal_OpcDec
1451: ENDFN CallPal_OpcDec8D
1452:
1453: ORG_CALL_PAL_UNPRIV(0x8E)
1454: CallPal_OpcDec8E:
1455: br CallPal_OpcDec
1456: ENDFN CallPal_OpcDec8E
1457:
1458: ORG_CALL_PAL_UNPRIV(0x8F)
1459: CallPal_OpcDec8F:
1460: br CallPal_OpcDec
1461: ENDFN CallPal_OpcDec8F
1462:
1463: ORG_CALL_PAL_UNPRIV(0x90)
1464: CallPal_OpcDec90:
1465: br CallPal_OpcDec
1466: ENDFN CallPal_OpcDec90
1467:
1468: ORG_CALL_PAL_UNPRIV(0x91)
1469: CallPal_OpcDec91:
1470: br CallPal_OpcDec
1471: ENDFN CallPal_OpcDec91
1472:
1473: ORG_CALL_PAL_UNPRIV(0x92)
1474: CallPal_OpcDec92:
1475: br CallPal_OpcDec
1476: ENDFN CallPal_OpcDec92
1477:
1478: ORG_CALL_PAL_UNPRIV(0x93)
1479: CallPal_OpcDec93:
1480: br CallPal_OpcDec
1481: ENDFN CallPal_OpcDec93
1482:
1483: ORG_CALL_PAL_UNPRIV(0x94)
1484: CallPal_OpcDec94:
1485: br CallPal_OpcDec
1486: ENDFN CallPal_OpcDec94
1487:
1488: ORG_CALL_PAL_UNPRIV(0x95)
1489: CallPal_OpcDec95:
1490: br CallPal_OpcDec
1491: ENDFN CallPal_OpcDec95
1492:
1493: ORG_CALL_PAL_UNPRIV(0x96)
1494: CallPal_OpcDec96:
1495: br CallPal_OpcDec
1496: ENDFN CallPal_OpcDec96
1497:
1498: ORG_CALL_PAL_UNPRIV(0x97)
1499: CallPal_OpcDec97:
1500: br CallPal_OpcDec
1501: ENDFN CallPal_OpcDec97
1502:
1503: ORG_CALL_PAL_UNPRIV(0x98)
1504: CallPal_OpcDec98:
1505: br CallPal_OpcDec
1506: ENDFN CallPal_OpcDec98
1507:
1508: ORG_CALL_PAL_UNPRIV(0x99)
1509: CallPal_OpcDec99:
1510: br CallPal_OpcDec
1511: ENDFN CallPal_OpcDec99
1512:
1513: ORG_CALL_PAL_UNPRIV(0x9A)
1514: CallPal_OpcDec9A:
1515: br CallPal_OpcDec
1516: ENDFN CallPal_OpcDec9A
1517:
1518: ORG_CALL_PAL_UNPRIV(0x9B)
1519: CallPal_OpcDec9B:
1520: br CallPal_OpcDec
1521: ENDFN CallPal_OpcDec9B
1522:
1523: ORG_CALL_PAL_UNPRIV(0x9C)
1524: CallPal_OpcDec9C:
1525: br CallPal_OpcDec
1526: ENDFN CallPal_OpcDec9C
1527:
1528: ORG_CALL_PAL_UNPRIV(0x9D)
1529: CallPal_OpcDec9D:
1530: br CallPal_OpcDec
1531: ENDFN CallPal_OpcDec9D
1532:
1533: /*
1534: * Read Unique Value
1535: *
1536: * OUTPUT PARAMETERS:
1537: *
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
1545:
1546: /*
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
1558:
1559: ORG_CALL_PAL_UNPRIV(0xA0)
1560: CallPal_OpcDecA0:
1561: br CallPal_OpcDec
1562: ENDFN CallPal_OpcDecA0
1563:
1564: ORG_CALL_PAL_UNPRIV(0xA1)
1565: CallPal_OpcDecA1:
1566: br CallPal_OpcDec
1567: ENDFN CallPal_OpcDecA1
1568:
1569: ORG_CALL_PAL_UNPRIV(0xA2)
1570: CallPal_OpcDecA2:
1571: br CallPal_OpcDec
1572: ENDFN CallPal_OpcDecA2
1573:
1574: ORG_CALL_PAL_UNPRIV(0xA3)
1575: CallPal_OpcDecA3:
1576: br CallPal_OpcDec
1577: ENDFN CallPal_OpcDecA3
1578:
1579: ORG_CALL_PAL_UNPRIV(0xA4)
1580: CallPal_OpcDecA4:
1581: br CallPal_OpcDec
1582: ENDFN CallPal_OpcDecA4
1583:
1584: ORG_CALL_PAL_UNPRIV(0xA5)
1585: CallPal_OpcDecA5:
1586: br CallPal_OpcDec
1587: ENDFN CallPal_OpcDecA5
1588:
1589: ORG_CALL_PAL_UNPRIV(0xA6)
1590: CallPal_OpcDecA6:
1591: br CallPal_OpcDec
1592: ENDFN CallPal_OpcDecA6
1593:
1594: ORG_CALL_PAL_UNPRIV(0xA7)
1595: CallPal_OpcDecA7:
1596: br CallPal_OpcDec
1597: ENDFN CallPal_OpcDecA7
1598:
1599: ORG_CALL_PAL_UNPRIV(0xA8)
1600: CallPal_OpcDecA8:
1601: br CallPal_OpcDec
1602: ENDFN CallPal_OpcDecA8
1603:
1604: ORG_CALL_PAL_UNPRIV(0xA9)
1605: CallPal_OpcDecA9:
1606: br CallPal_OpcDec
1607: ENDFN CallPal_OpcDecA9
1608:
1609: /*
1610: * Generate Trap
1611: *
1612: * OUTPUT PARAMETERS:
1613: *
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
1623:
1624: mfpr p0, ptEntIF
1625: mfpr $gp, ptKgp
1626: mov IF_K_GENTRAP, a0
1627: hw_ret (p0)
1628: ENDFN CallPal_GenTrap
1629:
1630: ORG_CALL_PAL_UNPRIV(0xAB)
1631: CallPal_OpcDecAB:
1632: br CallPal_OpcDec
1633: ENDFN CallPal_OpcDecAB
1634:
1635: ORG_CALL_PAL_UNPRIV(0xAC)
1636: CallPal_OpcDecAC:
1637: br CallPal_OpcDec
1638: ENDFN CallPal_OpcDecAC
1639:
1640: ORG_CALL_PAL_UNPRIV(0xAD)
1641: CallPal_OpcDecAD:
1642: br CallPal_OpcDec
1643: ENDFN CallPal_OpcDecAD
1644:
1645: ORG_CALL_PAL_UNPRIV(0xAE)
1646: CallPal_OpcDecAE:
1647: br CallPal_OpcDec
1648: ENDFN CallPal_OpcDecAE
1649:
1650: ORG_CALL_PAL_UNPRIV(0xAF)
1651: CallPal_OpcDecAF:
1652: br CallPal_OpcDec
1653: ENDFN CallPal_OpcDecAF
1654:
1655: ORG_CALL_PAL_UNPRIV(0xB0)
1656: CallPal_OpcDecB0:
1657: br CallPal_OpcDec
1658: ENDFN CallPal_OpcDecB0
1659:
1660: ORG_CALL_PAL_UNPRIV(0xB1)
1661: CallPal_OpcDecB1:
1662: br CallPal_OpcDec
1663: ENDFN CallPal_OpcDecB1
1664:
1665: ORG_CALL_PAL_UNPRIV(0xB2)
1666: CallPal_OpcDecB2:
1667: br CallPal_OpcDec
1668: ENDFN CallPal_OpcDecB2
1669:
1670: ORG_CALL_PAL_UNPRIV(0xB3)
1671: CallPal_OpcDecB3:
1672: br CallPal_OpcDec
1673: ENDFN CallPal_OpcDecB3
1674:
1675: ORG_CALL_PAL_UNPRIV(0xB4)
1676: CallPal_OpcDecB4:
1677: br CallPal_OpcDec
1678: ENDFN CallPal_OpcDecB4
1679:
1680: ORG_CALL_PAL_UNPRIV(0xB5)
1681: CallPal_OpcDecB5:
1682: br CallPal_OpcDec
1683: ENDFN CallPal_OpcDecB5
1684:
1685: ORG_CALL_PAL_UNPRIV(0xB6)
1686: CallPal_OpcDecB6:
1687: br CallPal_OpcDec
1688: ENDFN CallPal_OpcDecB6
1689:
1690: ORG_CALL_PAL_UNPRIV(0xB7)
1691: CallPal_OpcDecB7:
1692: br CallPal_OpcDec
1693: ENDFN CallPal_OpcDecB7
1694:
1695: ORG_CALL_PAL_UNPRIV(0xB8)
1696: CallPal_OpcDecB8:
1697: br CallPal_OpcDec
1698: ENDFN CallPal_OpcDecB8
1699:
1700: ORG_CALL_PAL_UNPRIV(0xB9)
1701: CallPal_OpcDecB9:
1702: br CallPal_OpcDec
1703: ENDFN CallPal_OpcDecB9
1704:
1705: ORG_CALL_PAL_UNPRIV(0xBA)
1706: CallPal_OpcDecBA:
1707: br CallPal_OpcDec
1708: ENDFN CallPal_OpcDecBA
1709:
1710: ORG_CALL_PAL_UNPRIV(0xBB)
1711: CallPal_OpcDecBB:
1712: br CallPal_OpcDec
1713: ENDFN CallPal_OpcDecBB
1714:
1715: ORG_CALL_PAL_UNPRIV(0xBC)
1716: CallPal_OpcDecBC:
1717: br CallPal_OpcDec
1718: ENDFN CallPal_OpcDecBC
1719:
1720: ORG_CALL_PAL_UNPRIV(0xBD)
1721: CallPal_OpcDecBD:
1722: br CallPal_OpcDec
1723: ENDFN CallPal_OpcDecBD
1724:
1725: ORG_CALL_PAL_UNPRIV(0xBE)
1726: CallPal_OpcDecBE:
1727: br CallPal_OpcDec
1728: ENDFN CallPal_OpcDecBE
1729:
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
1735:
1736: mfpr p0, ptEntIF
1737: mfpr $gp, ptKgp
1738: mov IF_K_OPCDEC, a0
1739: hw_ret (p0)
1740: ENDFN CallPal_OpcDec
1741:
1742: .org 0x3000
1743: .text 1
1744: /*
1745: * PALcode detected processor machine check handler.
1746: *
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.
1754: *
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:
1767: *
1768: * r14 (p6) = Exception address
1769: *
1770: * OUTPUT PARAMETERS:
1771: *
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:
1783: *
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: */
1789:
1790: MchkBugCheck:
1791: MchkOSBugCheck:
1792: halt
1793: ENDFN MchkBugCheck
1794:
1795: /*
1796: * Common Machine Check Handler
1797: *
1798: * INPUT STATE:
1799: *
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
1809: *
1810: * Registers v0, t0, and t3 .. t5 are available for use, in
1811: * addition to the shadow registers.
1812: */
1813:
1814: MchkCommon:
1815: halt
1816: ENDFN MchkCommon
1817:
1818: /*
1819: * Build Machine Check Logout Frame
1820: *
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.
1830: *
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: */
1837:
1838: .macro STORE_IPR which, offset, base
1839: mfpr v0, \which
1840: stq_p v0, \offset(\base)
1841: .endm
1842:
1843: MchkLogOut:
1844: halt
1845: ENDFN MchkLogOut
1846:
1847: MchkDouble:
1848: bsr p7, UpdatePCB
1849: lda v0, HLT_K_DBL_MCHK
1850: br Sys_EnterConsole
1851: ENDFN MchkDouble
1852:
1853: MchkFromPal:
1854: bsr p7, UpdatePCB
1855: lda v0, HLT_K_MCHK_FROM_PAL
1856: br Sys_EnterConsole
1857: ENDFN MchkFromPal
1858:
1859: MchkKspInvalid:
1860: bsr p7, UpdatePCB
1861: lda v0, HLT_K_KSP_INVAL
1862: br Sys_EnterConsole
1863: ENDFN MchkKspInvalid
1864:
1865: /*
1866: * Update the current PCB with new SP and CC info.
1867: *
1868: * INPUT PARAMETERS:
1869: *
1870: * p7 = return linkage
1871: */
1872:
1873: UpdatePCB:
1874: rpcc p5
1875: mfpr p4, ptPcbb
1876:
1877: mfpr p3, qemu_ps // Check current mode
1878: and p3, PS_M_CM, p3
1879: beq p3, 1f
1880:
1881: mtpr $sp, qemu_usp // Save user stack pointer
1882: stq_p $sp, PCB_Q_USP(p4)
1883: br 2f
1884:
1885: 1: mtpr $sp, ptKsp // Save kernel stack pointer
1886: stq_p $sp, PCB_Q_KSP(p4)
1887:
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
1891:
1892: mfpr p5, qemu_unique // Save unique
1893: stq_p p5, PCB_Q_UNIQUE(p4)
1894:
1895: ret $31, (p7), 0
1896: ENDFN UpdatePCB
1897:
1898: /*
1899: * FIXME
1900: */
1901: Sys_EnterConsole:
1902: halt
1903:
1904: /*
1905: * Allocate the initial bootup stack.
1906: */
1907:
1908: .section .bss
1909: .align 3
1910: .globl stack
1911: .type stack,@object
1912: .size stack,STACK_SIZE
1913: stack: .skip STACK_SIZE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.