2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
27 #include <mach_kgdb.h>
28 #include <mach_debug.h>
31 #include <ppc/proc_reg.h>
32 #include <mach/ppc/vm_param.h>
35 * vm_offset_t getrpc(void) - Return address of the function
36 * that called the current function
39 /* By using this function, we force the caller to save its LR in a known
40 * location, which we can pick up and return. See PowerPC ELF specs.
42 ENTRY(getrpc, TAG_NO_FRAME_USED)
43 lwz ARG0, FM_BACKPTR(r1) /* Load our backchain ptr */
44 lwz ARG0, FM_LR_SAVE(ARG0) /* Load previously saved LR */
49 * General entry for all debuggers. This gets us onto the debug stack and
50 * then back off at exit. We need to pass back R3 to caller.
53 ENTRY(Call_Debugger, TAG_NO_FRAME_USED)
56 lis r8,hi16(MASK(MSR_VEC)) ; Get the vector flag
57 mfmsr r7 ; Get the current MSR
58 ori r8,r8,lo16(MASK(MSR_EE)|MASK(MSR_FP)) ; Add the FP flag
59 mflr r0 ; Save the return
60 andc r7,r7,r8 ; Clear VEC and FP
63 mfsprg r8,1 ; Get the current activation
64 lwz r8,ACT_PER_PROC(r8) ; Get the per_proc block
65 stw r0,FM_LR_SAVE(r1) ; Save return on current stack
67 lwz r9,PP_DEBSTACKPTR(r8) ; Get the debug stack
68 cmpwi r9,0 ; Are we already on it?
71 mr r9,r1 ; We are already on the stack, so use the current value
72 subi r9,r9,FM_REDZONE+FM_SIZE ; Carve some extra space here
74 cdNewDeb: li r0,0 ; Clear this out
75 stw r1,FM_ARG0(r9) ; Save the old stack pointer as if it were the first arg
77 stw r0,PP_DEBSTACKPTR(r8) ; Mark debug stack as busy
79 subi r1,r9,FM_SIZE ; Carve a new frame
80 stw r0,FM_BACKPTR(r1) ; Chain back
82 bl EXT(Call_DebuggerC) ; Call the "C" phase of this
84 lis r8,hi16(MASK(MSR_VEC)) ; Get the vector flag
85 mfmsr r0 ; Get the current MSR
86 ori r8,r8,lo16(MASK(MSR_EE)|MASK(MSR_FP)) ; Add the FP flag
87 addi r1,r1,FM_SIZE ; Pop off first stack frame
88 andc r0,r0,r8 ; Turn off all the interesting stuff
91 mfsprg r8,1 ; Get the current activation
92 lwz r8,ACT_PER_PROC(r8) ; Get the per_proc block
94 lwz r9,PP_DEBSTACK_TOP_SS(r8) ; Get the top of the stack
95 cmplw r1,r9 ; Have we hit the bottom of the debug stack?
96 lwz r1,FM_ARG0(r1) ; Get previous stack frame
97 lwz r0,FM_LR_SAVE(r1) ; Get return address
98 mtlr r0 ; Set the return point
99 bnelr ; Return if still on debug stack
101 stw r9,PP_DEBSTACKPTR(r8) ; Mark debug stack as free
105 /* The following routines are for C-support. They are usually
106 * inlined into the C using the specifications in proc_reg.h,
107 * but if optimisation is switched off, the inlining doesn't work
110 ENTRY(get_got, TAG_NO_FRAME_USED)
114 ENTRY(mflr, TAG_NO_FRAME_USED)
118 ENTRY(mfpvr, TAG_NO_FRAME_USED)
122 ENTRY(mtmsr, TAG_NO_FRAME_USED)
127 ENTRY(mfmsr, TAG_NO_FRAME_USED)
131 ENTRY(mtsrin, TAG_NO_FRAME_USED)
137 ENTRY(mfsrin, TAG_NO_FRAME_USED)
141 ENTRY(mtsdr1, TAG_NO_FRAME_USED)
145 ENTRY(mtdar, TAG_NO_FRAME_USED)
149 ENTRY(mfdar, TAG_NO_FRAME_USED)
153 ENTRY(mtdec, TAG_NO_FRAME_USED)
157 ENTRY(cntlzw, TAG_NO_FRAME_USED)
161 /* Decrementer frequency and realtime|timebase processor registers
162 * are different between ppc601 and ppc603/4, we define them all.
165 ENTRY(isync_mfdec, TAG_NO_FRAME_USED)
171 ENTRY(mftb, TAG_NO_FRAME_USED)
175 ENTRY(mftbu, TAG_NO_FRAME_USED)
179 ENTRY(mfrtcl, TAG_NO_FRAME_USED)
183 ENTRY(mfrtcu, TAG_NO_FRAME_USED)
187 ENTRY(tlbie, TAG_NO_FRAME_USED)
193 * Performance Monitor Register Support
196 ENTRY(mfmmcr0, TAG_NO_FRAME_USED)
200 ENTRY(mtmmcr0, TAG_NO_FRAME_USED)
204 ENTRY(mfmmcr1, TAG_NO_FRAME_USED)
208 ENTRY(mtmmcr1, TAG_NO_FRAME_USED)
212 ENTRY(mfmmcr2, TAG_NO_FRAME_USED)
216 ENTRY(mtmmcr2, TAG_NO_FRAME_USED)
220 ENTRY(mfpmc1, TAG_NO_FRAME_USED)
224 ENTRY(mtpmc1, TAG_NO_FRAME_USED)
228 ENTRY(mfpmc2, TAG_NO_FRAME_USED)
232 ENTRY(mtpmc2, TAG_NO_FRAME_USED)
236 ENTRY(mfpmc3, TAG_NO_FRAME_USED)
240 ENTRY(mtpmc3, TAG_NO_FRAME_USED)
244 ENTRY(mfpmc4, TAG_NO_FRAME_USED)
248 ENTRY(mtpmc4, TAG_NO_FRAME_USED)
252 ENTRY(mfsia, TAG_NO_FRAME_USED)
256 ENTRY(mfsda, TAG_NO_FRAME_USED)
260 .globl EXT(hid0get64)
263 mfspr r4,hid0 ; Get the HID0
264 srdi r3,r4,32 ; Move top down
265 rlwinm r4,r4,0,0,31 ; Clean top
268 .globl EXT(hid5set64)
271 rlwinm r3,r3,0,1,0 ; Copy low 32 int high 32
272 rlwimi r3,r4,0,0,31 ; Inser the low part behind top
273 mtspr hid5,r3 ; Set it