|
|
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.