|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: ! 26: #include <debug.h> ! 27: ! 28: #include <mach/ppc/thread_status.h> ! 29: #include <mach/machine/vm_types.h> ! 30: #include <kern/thread.h> ! 31: #include <machdep/ppc/proc_reg.h> ! 32: #include <machdep/ppc/pmap.h> ! 33: #include <machdep/ppc/exception.h> ! 34: ! 35: #define KGDB_DEBUG(x) kprintf x ! 36: ! 37: /* ! 38: * copyin/out_multiple - the assembler copyin/out functions jump to C for ! 39: * help when the copyin lies over a segment boundary. The C breaks ! 40: * down the copy into two sub-copies and re-calls the assembler with ! 41: * these sub-copies. Very rare occurrance. Warning: These functions are ! 42: * called whilst active_thread->thread_recover is still set. ! 43: */ ! 44: ! 45: extern boolean_t copyin_multiple(const char *src, ! 46: char *dst, ! 47: vm_size_t count); ! 48: ! 49: boolean_t copyin_multiple(const char *src, ! 50: char *dst, ! 51: vm_size_t count) ! 52: { ! 53: const char *midpoint; ! 54: vm_size_t first_count; ! 55: boolean_t first_result; ! 56: ! 57: /* Assert that we've been called because of a segment boundary, ! 58: * this function is more expensive than the assembler, and should ! 59: * only be called in this difficult case. ! 60: */ ! 61: assert(((vm_offset_t)src & 0xF0000000) != ! 62: ((vm_offset_t)(src + count -1) & 0xF0000000)); ! 63: #if DEBUG ! 64: KGDB_DEBUG(("copyin across segment boundary," ! 65: "src=0x%08x, dst=0x%08x, count=0x%x\n", src, dst, count)); ! 66: #endif /* DEBUG */ ! 67: /* TODO NMGS define sensible constants for segments, and apply ! 68: * to C and assembler (assembler is much harder) ! 69: */ ! 70: midpoint = (const char*) ((vm_offset_t)(src + count) & 0xF0000000); ! 71: first_count = (midpoint - src); ! 72: ! 73: #if DEBUG ! 74: KGDB_DEBUG(("copyin across segment boundary : copyin(" ! 75: "src=0x%08x, dst=0x%08x ,count=0x%x)\n", ! 76: src, dst, first_count)); ! 77: #endif /* DEBUG */ ! 78: first_result = copyin(src, dst, first_count); ! 79: ! 80: /* If there was an error, stop now and return error */ ! 81: if (first_result != 0) ! 82: return first_result; ! 83: ! 84: /* otherwise finish the job and return result */ ! 85: #if DEBUG ! 86: KGDB_DEBUG(("copyin across segment boundary : copyin(" ! 87: "src=0x%08x, dst=0x%08x, count=0x%x)\n", ! 88: midpoint, dst+first_count, count-first_count)); ! 89: #endif /* DEBUG */ ! 90: ! 91: return copyin(midpoint, dst + first_count, count-first_count); ! 92: } ! 93: ! 94: extern int copyout_multiple(const char *src, char *dst, vm_size_t count); ! 95: ! 96: extern int copyout_multiple(const char *src, char *dst, vm_size_t count) ! 97: { ! 98: char *midpoint; ! 99: vm_size_t first_count; ! 100: boolean_t first_result; ! 101: ! 102: /* Assert that we've been called because of a segment boundary, ! 103: * this function is more expensive than the assembler, and should ! 104: * only be called in this difficult case. For copyout, the ! 105: * segment boundary is on the dst ! 106: */ ! 107: assert(((vm_offset_t)dst & 0xF0000000) != ! 108: ((vm_offset_t)(dst + count - 1) & 0xF0000000)); ! 109: ! 110: #if DEBUG ! 111: KGDB_DEBUG(("copyout across segment boundary," ! 112: "src=0x%08x, dst=0x%08x, count=0x%x\n", src, dst, count)); ! 113: #endif /* DEBUG */ ! 114: ! 115: /* TODO NMGS define sensible constants for segments, and apply ! 116: * to C and assembler (assembler is much harder) ! 117: */ ! 118: midpoint = (char *) ((vm_offset_t)(dst + count) & 0xF0000000); ! 119: first_count = (midpoint - dst); ! 120: ! 121: #if DEBUG ! 122: KGDB_DEBUG(("copyout across segment boundary : copyout(" ! 123: "src=0x%08x, dst=0x%08x, count=0x%x)\n", src, dst, count)); ! 124: #endif /* DEBUG */ ! 125: first_result = copyout(src, dst, first_count); ! 126: ! 127: /* If there was an error, stop now and return error */ ! 128: if (first_result != 0) ! 129: return first_result; ! 130: ! 131: /* otherwise finish the job and return result */ ! 132: ! 133: #if DEBUG ! 134: KGDB_DEBUG(("copyout across segment boundary : copyout(" ! 135: "src=0x%08x, dst=0x%08x, count=0x%x)\n", ! 136: src + first_count, midpoint, count-first_count)); ! 137: #endif /* DEBUG */ ! 138: ! 139: return copyout(src + first_count, midpoint, count-first_count); ! 140: } ! 141: ! 142: ! 143: /* TODO NMGS Mutexes aren't implemented yet. for now define dummies */ ! 144: ! 145: #include <kern/lock.h> ! 146: ! 147: #if DEBUG ! 148: /* ! 149: * This is a debugging routine, calling the assembler routine-proper ! 150: * ! 151: * Load the context for the first kernel thread, and go. ! 152: */ ! 153: ! 154: extern void load_context(thread_t thread); ! 155: ! 156: #define DPRINTF(x) kprintf x ! 157: ! 158: void load_context(thread_t thread) ! 159: { ! 160: struct ppc_kernel_state *kss; ! 161: ! 162: #if 0 ! 163: DPRINTF(("thread addr =0x%08x\n",thread)); ! 164: DPRINTF(("thread pcb.ksp=0x%08x\n",thread->pcb->ksp)); ! 165: DPRINTF(("thread kstack =0x%08x\n",thread->kernel_stack)); ! 166: kss = STACK_IKS(thread->kernel_stack); ! 167: DPRINTF(("thread kss.r1 =0x%08x\n",kss->r1)); ! 168: DPRINTF(("thread kss.lr =0x%08x\n",kss->lr)); ! 169: DPRINTF(("calling Load_context\n")); ! 170: #endif /* 0 */ ! 171: Load_context(thread); ! 172: } ! 173: #endif /* DEBUG */ ! 174: ! 175: #if DEBUG ! 176: #define kgdb_printf kprintf ! 177: #define NULL 0 ! 178: void regDump(struct ppc_saved_state *state) ! 179: { ! 180: int i; ! 181: ! 182: for (i=0; i<32; i++) { ! 183: if ((i % 8) == 0) ! 184: kgdb_printf("\n%4d :",i); ! 185: kgdb_printf(" %08x",*(&state->r0+i)); ! 186: } ! 187: ! 188: kgdb_printf("\n"); ! 189: kgdb_printf("cr = 0x%08x\t\t",state->cr); ! 190: kgdb_printf("xer = 0x%08x\n",state->xer); ! 191: kgdb_printf("lr = 0x%08x\t\t",state->lr); ! 192: kgdb_printf("ctr = 0x%08x\n",state->ctr); ! 193: kgdb_printf("srr0(iar) = 0x%08x\t\t",state->srr0); ! 194: kgdb_printf("srr1(msr) = 0x%08x\n",state->srr1); ! 195: /*kgdb_printf("srr1(msr) = 0x%08B\n",state->srr1, ! 196: "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18" ! 197: "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT");*/ ! 198: kgdb_printf("mq = 0x%08x\t\t",state->mq); ! 199: kgdb_printf("sr_copyin = 0x%08x\n",state->sr_copyin); ! 200: kgdb_printf("\n"); ! 201: ! 202: /* Be nice - for user tasks, generate some stack trace */ ! 203: if (state->srr1 & MASK(MSR_PR)) { ! 204: char *addr = (char*)state->r1; ! 205: unsigned int buf[2]; ! 206: for (i = 0; i < 8; i++) { ! 207: if (addr == (char*)NULL) ! 208: break; ! 209: if (!copyin(addr,(char*)buf, 2 * sizeof(int))) { ! 210: printf("0x%08x : %08x\n",buf[0],buf[1]); ! 211: addr = (char*)buf[0]; ! 212: } else { ! 213: break; ! 214: } ! 215: } ! 216: } ! 217: } ! 218: ! 219: struct ppc_saved_state *enterDebugger(unsigned int trap, ! 220: struct ppc_saved_state *ssp, ! 221: unsigned int dsisr) ! 222: { ! 223: KGDB_DEBUG(("trap = 0x%x (no=0x%x), dsisr=0x%08x\n", ! 224: trap, trap / EXC_VECTOR_SIZE,dsisr)); ! 225: KGDB_DEBUG(("%c\n%s iar=0x%08x dar=0x%08x dsisr 0x%08b\n", ! 226: 7, ! 227: trap_type[trap / EXC_VECTOR_SIZE], ! 228: ssp->srr0,mfdar(), ! 229: dsisr,"\20\02NO_TRANS\05PROT\06ILL_I/O\07STORE\12DABR\15EAR")); ! 230: ! 231: //kgdb_trap(trap, trap, ssp); ! 232: //call_kdp(); ! 233: enter_debugger(trap, 0, 0, ssp, 1); ! 234: ! 235: return ssp; ! 236: } ! 237: #endif /* DEBUG */ ! 238:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.