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