|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 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. ! 11: * ! 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 ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: #include <debug.h> ! 26: #include <mach_debug.h> ! 27: ! 28: #include <mach/ppc/thread_status.h> ! 29: #include <mach/vm_types.h> ! 30: #include <kern/thread.h> ! 31: #include <kern/misc_protos.h> ! 32: #include <ppc/proc_reg.h> ! 33: #include <ppc/pmap.h> ! 34: #include <ppc/misc_protos.h> ! 35: #include <ppc/exception.h> ! 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: ! 64: /* TODO NMGS define sensible constants for segments, and apply ! 65: * to C and assembler (assembler is much harder) ! 66: */ ! 67: midpoint = (const char*) ((vm_offset_t)(src + count) & 0xF0000000); ! 68: first_count = (midpoint - src); ! 69: ! 70: first_result = copyin(src, dst, first_count); ! 71: ! 72: /* If there was an error, stop now and return error */ ! 73: if (first_result != 0) ! 74: return first_result; ! 75: ! 76: /* otherwise finish the job and return result */ ! 77: return copyin(midpoint, dst + first_count, count-first_count); ! 78: } ! 79: ! 80: extern int copyout_multiple(const char *src, char *dst, vm_size_t count); ! 81: ! 82: int copyout_multiple(const char *src, char *dst, vm_size_t count) ! 83: { ! 84: char *midpoint; ! 85: vm_size_t first_count; ! 86: boolean_t first_result; ! 87: ! 88: /* Assert that we've been called because of a segment boundary, ! 89: * this function is more expensive than the assembler, and should ! 90: * only be called in this difficult case. For copyout, the ! 91: * segment boundary is on the dst ! 92: */ ! 93: assert(((vm_offset_t)dst & 0xF0000000) != ! 94: ((vm_offset_t)(dst + count - 1) & 0xF0000000)); ! 95: ! 96: /* TODO NMGS define sensible constants for segments, and apply ! 97: * to C and assembler (assembler is much harder) ! 98: */ ! 99: midpoint = (char *) ((vm_offset_t)(dst + count) & 0xF0000000); ! 100: first_count = (midpoint - dst); ! 101: ! 102: first_result = copyout(src, dst, first_count); ! 103: ! 104: /* If there was an error, stop now and return error */ ! 105: if (first_result != 0) ! 106: return first_result; ! 107: ! 108: /* otherwise finish the job and return result */ ! 109: ! 110: return copyout(src + first_count, midpoint, count-first_count); ! 111: } ! 112: ! 113: int bcmp( ! 114: const char *a, ! 115: const char *b, ! 116: vm_size_t len) ! 117: { ! 118: if (len == 0) ! 119: return 0; ! 120: ! 121: do ! 122: if (*a++ != *b++) ! 123: break; ! 124: while (--len); ! 125: ! 126: return len; ! 127: } ! 128: ! 129: #if DEBUG ! 130: void regDump(struct ppc_saved_state *state) ! 131: { ! 132: int i; ! 133: ! 134: for (i=0; i<32; i++) { ! 135: if ((i % 8) == 0) ! 136: kprintf("\n%4d :",i); ! 137: kprintf(" %08x",*(&state->r0+i)); ! 138: } ! 139: ! 140: kprintf("\n"); ! 141: kprintf("cr = 0x%08x\t\t",state->cr); ! 142: kprintf("xer = 0x%08x\n",state->xer); ! 143: kprintf("lr = 0x%08x\t\t",state->lr); ! 144: kprintf("ctr = 0x%08x\n",state->ctr); ! 145: kprintf("srr0(iar) = 0x%08x\t\t",state->srr0); ! 146: kprintf("srr1(msr) = 0x%08B\n",state->srr1, ! 147: "\x10\x11""EE\x12PR\x13""FP\x14ME\x15""FE0\x16SE\x18" ! 148: "FE1\x19""AL\x1a""EP\x1bIT\x1c""DT"); ! 149: kprintf("mq = 0x%08x\t\t",state->mq); ! 150: kprintf("sr_copyin = 0x%08x\n",state->sr_copyin); ! 151: kprintf("\n"); ! 152: ! 153: /* Be nice - for user tasks, generate some stack trace */ ! 154: if (state->srr1 & MASK(MSR_PR)) { ! 155: char *addr = (char*)state->r1; ! 156: unsigned int buf[2]; ! 157: for (i = 0; i < 8; i++) { ! 158: if (addr == (char*)NULL) ! 159: break; ! 160: if (!copyin(addr,(char*)buf, 2 * sizeof(int))) { ! 161: printf("0x%08x : %08x\n",buf[0],buf[1]); ! 162: addr = (char*)buf[0]; ! 163: } else { ! 164: break; ! 165: } ! 166: } ! 167: } ! 168: } ! 169: #endif /* DEBUG */ ! 170: ! 171: #ifdef 0 ! 172: /* ! 173: * invalidate_cache_for_io ! 174: * ! 175: * Takes cache of those requests which may require to flush the ! 176: * data cache first before invalidation. ! 177: */ ! 178: ! 179: ! 180: void ! 181: invalidate_cache_for_io(vm_offset_t area, unsigned count, boolean_t phys) ! 182: { ! 183: vm_offset_t aligned_start, aligned_end, end; ! 184: ! 185: /* For unaligned reads we need to flush any ! 186: * unaligned cache lines. We invalidate the ! 187: * rest as this is faster ! 188: */ ! 189: ! 190: aligned_start = area & ~(CACHE_LINE_SIZE-1); ! 191: if (aligned_start != area) ! 192: flush_dcache(aligned_start, CACHE_LINE_SIZE, phys); ! 193: ! 194: end = area + count; ! 195: aligned_end = (end & ~(CACHE_LINE_SIZE-1)); ! 196: if (aligned_end != end) ! 197: flush_dcache(aligned_end, CACHE_LINE_SIZE, phys); ! 198: ! 199: invalidate_dcache(area, count, phys); ! 200: } ! 201: ! 202: extern void tracecopyin(unsigned int src, unsigned int dest, unsigned int lgn, unsigned int from); ! 203: void tracecopyin(unsigned int src, unsigned int dest, unsigned int lgn, unsigned int from) { ! 204: ! 205: spl_t spl; ! 206: ! 207: spl = splhigh(); ! 208: printf("Copy in called from %08X: src=%08X; dest=%08X; lgn=%08X\n", from, src, dest, lgn); ! 209: splx(spl); ! 210: return; ! 211: } ! 212: ! 213: extern void tracecopyout(unsigned int src, unsigned int dest, unsigned int lgn, unsigned int from); ! 214: void tracecopyout(unsigned int src, unsigned int dest, unsigned int lgn, unsigned int from) { ! 215: ! 216: spl_t spl; ! 217: ! 218: spl = splhigh(); ! 219: printf("Copy out called from %08X: src=%08X; dest=%08X; lgn=%08X\n", from, src, dest, lgn); ! 220: splx(spl); ! 221: return; ! 222: } ! 223: ! 224: extern void tracecopystr(unsigned int src, unsigned int dest, unsigned int max, ! 225: unsigned int lgn, unsigned int from); ! 226: void tracecopystr(unsigned int src, unsigned int dest, unsigned int max, ! 227: unsigned int lgn, unsigned int from) { ! 228: ! 229: spl_t spl; ! 230: ! 231: spl = splhigh(); ! 232: printf("Copy in string called from %08X: src=%08X; dest=%08X; max=%08X; lgnadr=%08X\n", ! 233: from, src, dest, max, lgn); ! 234: splx(spl); ! 235: return; ! 236: } ! 237: ! 238: unsigned int ExceptionTrace = 0; ! 239: extern void ExceptionTracePrint(struct savearea *sv, int type); ! 240: void ExceptionTracePrint(struct savearea *sv, int type) { ! 241: ! 242: spl_t spl; ! 243: ! 244: spl = splhigh(); ! 245: ! 246: if(type) { ! 247: printf(" Trap from %08X, type=%08X, R0=%08X, R1=%08X, R3=%08X, LR=%08X, AST=%08X\n", ! 248: sv->save_srr0, sv->save_exception, sv->save_r0, sv->save_r1, sv->save_r3, ! 249: sv->save_lr, need_ast[0]); ! 250: } ! 251: else { ! 252: printf("Syscall from %08X, type=%08X, R0=%08X, R1=%08X, R3=%08X, LR=%08X, AST=%08X\n", ! 253: sv->save_srr0, sv->save_exception, sv->save_r0, sv->save_r1, sv->save_r3, ! 254: sv->save_lr, need_ast[0]); ! 255: } ! 256: splx(spl); ! 257: return; ! 258: } ! 259: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.