1/* 2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31 32#include <mach_kdb.h> 33#include <mach_kgdb.h> 34#include <mach_debug.h> 35#include <assym.s> 36#include <ppc/asm.h> 37#include <ppc/proc_reg.h> 38#include <mach/ppc/vm_param.h> 39 40/* 41 * vm_offset_t getrpc(void) - Return address of the function 42 * that called the current function 43 */ 44 45/* By using this function, we force the caller to save its LR in a known 46 * location, which we can pick up and return. See PowerPC ELF specs. 47 */ 48ENTRY(getrpc, TAG_NO_FRAME_USED) 49 lwz ARG0, FM_BACKPTR(r1) /* Load our backchain ptr */ 50 lwz ARG0, FM_LR_SAVE(ARG0) /* Load previously saved LR */ 51 blr /* And return */ 52 53 54/* 55 * General entry for all debuggers. This gets us onto the debug stack and 56 * then back off at exit. We need to pass back R3 to caller. 57 */ 58 59ENTRY(Call_Debugger, TAG_NO_FRAME_USED) 60 61 62 lis r8,hi16(MASK(MSR_VEC)) ; Get the vector flag 63 mfmsr r7 ; Get the current MSR 64 ori r8,r8,lo16(MASK(MSR_EE)|MASK(MSR_FP)) ; Add the FP flag 65 mflr r0 ; Save the return 66 andc r7,r7,r8 ; Clear VEC and FP 67 mtmsr r7 ; Do it 68 isync 69 mfsprg r8,1 ; Get the current activation 70 lwz r8,ACT_PER_PROC(r8) ; Get the per_proc block 71 stw r0,FM_LR_SAVE(r1) ; Save return on current stack 72 73 lwz r9,PP_DEBSTACKPTR(r8) ; Get the debug stack 74 cmpwi r9,0 ; Are we already on it? 75 bne cdNewDeb ; No... 76 77 mr r9,r1 ; We are already on the stack, so use the current value 78 subi r9,r9,FM_REDZONE+FM_SIZE ; Carve some extra space here 79 80cdNewDeb: li r0,0 ; Clear this out 81 stw r1,FM_ARG0(r9) ; Save the old stack pointer as if it were the first arg 82 83 stw r0,PP_DEBSTACKPTR(r8) ; Mark debug stack as busy 84 85 subi r1,r9,FM_SIZE ; Carve a new frame 86 stw r0,FM_BACKPTR(r1) ; Chain back 87 88 bl EXT(Call_DebuggerC) ; Call the "C" phase of this 89 90 lis r8,hi16(MASK(MSR_VEC)) ; Get the vector flag 91 mfmsr r0 ; Get the current MSR 92 ori r8,r8,lo16(MASK(MSR_EE)|MASK(MSR_FP)) ; Add the FP flag 93 addi r1,r1,FM_SIZE ; Pop off first stack frame 94 andc r0,r0,r8 ; Turn off all the interesting stuff 95 mtmsr r0 96 97 mfsprg r8,1 ; Get the current activation 98 lwz r8,ACT_PER_PROC(r8) ; Get the per_proc block 99 100 lwz r9,PP_DEBSTACK_TOP_SS(r8) ; Get the top of the stack 101 cmplw r1,r9 ; Have we hit the bottom of the debug stack? 102 lwz r1,FM_ARG0(r1) ; Get previous stack frame 103 lwz r0,FM_LR_SAVE(r1) ; Get return address 104 mtlr r0 ; Set the return point 105 bnelr ; Return if still on debug stack 106 107 stw r9,PP_DEBSTACKPTR(r8) ; Mark debug stack as free 108 blr 109 110 111/* The following routines are for C-support. They are usually 112 * inlined into the C using the specifications in proc_reg.h, 113 * but if optimisation is switched off, the inlining doesn't work 114 */ 115 116ENTRY(get_got, TAG_NO_FRAME_USED) 117 mr ARG0, r2 118 blr 119 120ENTRY(mflr, TAG_NO_FRAME_USED) 121 mflr ARG0 122 blr 123 124ENTRY(mfpvr, TAG_NO_FRAME_USED) 125 mfpvr ARG0 126 blr 127 128ENTRY(mtmsr, TAG_NO_FRAME_USED) 129 mtmsr ARG0 130 isync 131 blr 132 133ENTRY(mfmsr, TAG_NO_FRAME_USED) 134 mfmsr ARG0 135 blr 136 137ENTRY(mtsrin, TAG_NO_FRAME_USED) 138 isync 139 mtsrin ARG0, ARG1 140 isync 141 blr 142 143ENTRY(mfsrin, TAG_NO_FRAME_USED) 144 mfsrin ARG0, ARG0 145 blr 146 147ENTRY(mtsdr1, TAG_NO_FRAME_USED) 148 mtsdr1 ARG0 149 blr 150 151ENTRY(mtdar, TAG_NO_FRAME_USED) 152 mtdar ARG0 153 blr 154 155ENTRY(mfdar, TAG_NO_FRAME_USED) 156 mfdar ARG0 157 blr 158 159ENTRY(mtdec, TAG_NO_FRAME_USED) 160 mtdec ARG0 161 blr 162 163ENTRY(cntlzw, TAG_NO_FRAME_USED) 164 cntlzw r3,r3 165 blr 166 167/* Decrementer frequency and realtime|timebase processor registers 168 * are different between ppc601 and ppc603/4, we define them all. 169 */ 170 171ENTRY(isync_mfdec, TAG_NO_FRAME_USED) 172 isync 173 mfdec ARG0 174 blr 175 176 177ENTRY(mftb, TAG_NO_FRAME_USED) 178 mftb ARG0 179 blr 180 181ENTRY(mftbu, TAG_NO_FRAME_USED) 182 mftbu ARG0 183 blr 184 185ENTRY(mfrtcl, TAG_NO_FRAME_USED) 186 mfspr ARG0, 5 187 blr 188 189ENTRY(mfrtcu, TAG_NO_FRAME_USED) 190 mfspr ARG0, 4 191 blr 192 193ENTRY(tlbie, TAG_NO_FRAME_USED) 194 tlbie ARG0 195 blr 196 197 198/* 199 * Performance Monitor Register Support 200 */ 201 202ENTRY(mfmmcr0, TAG_NO_FRAME_USED) 203 mfspr r3,mmcr0 204 blr 205 206ENTRY(mtmmcr0, TAG_NO_FRAME_USED) 207 mtspr mmcr0,r3 208 blr 209 210ENTRY(mfmmcr1, TAG_NO_FRAME_USED) 211 mfspr r3,mmcr1 212 blr 213 214ENTRY(mtmmcr1, TAG_NO_FRAME_USED) 215 mtspr mmcr1,r3 216 blr 217 218ENTRY(mfmmcr2, TAG_NO_FRAME_USED) 219 mfspr r3,mmcr2 220 blr 221 222ENTRY(mtmmcr2, TAG_NO_FRAME_USED) 223 mtspr mmcr2,r3 224 blr 225 226ENTRY(mfpmc1, TAG_NO_FRAME_USED) 227 mfspr r3,pmc1 228 blr 229 230ENTRY(mtpmc1, TAG_NO_FRAME_USED) 231 mtspr pmc1,r3 232 blr 233 234ENTRY(mfpmc2, TAG_NO_FRAME_USED) 235 mfspr r3,pmc2 236 blr 237 238ENTRY(mtpmc2, TAG_NO_FRAME_USED) 239 mtspr pmc2,r3 240 blr 241 242ENTRY(mfpmc3, TAG_NO_FRAME_USED) 243 mfspr r3,pmc3 244 blr 245 246ENTRY(mtpmc3, TAG_NO_FRAME_USED) 247 mtspr pmc3,r3 248 blr 249 250ENTRY(mfpmc4, TAG_NO_FRAME_USED) 251 mfspr r3,pmc4 252 blr 253 254ENTRY(mtpmc4, TAG_NO_FRAME_USED) 255 mtspr pmc4,r3 256 blr 257 258ENTRY(mfsia, TAG_NO_FRAME_USED) 259 mfspr r3,sia 260 blr 261 262ENTRY(mfsda, TAG_NO_FRAME_USED) 263 mfspr r3,sda 264 blr 265 266 .globl EXT(hid1get) 267LEXT(hid1get) 268 269 mfspr r3,hid1 ; Get the HID1 270 blr 271 272 .globl EXT(hid0get64) 273LEXT(hid0get64) 274 275 mfspr r4,hid0 ; Get the HID0 276 srdi r3,r4,32 ; Move top down 277 rlwinm r4,r4,0,0,31 ; Clean top 278 blr 279 280 .globl EXT(hid5set64) 281LEXT(hid5set64) 282 283 rlwinm r3,r3,0,1,0 ; Copy low 32 int high 32 284 rlwimi r3,r4,0,0,31 ; Inser the low part behind top 285 mtspr hid5,r3 ; Set it 286 isync ; Wait for it 287 blr 288