2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
26 #include <mach_debug.h>
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>
34 #include <ppc/misc_protos.h>
35 #include <ppc/exception.h>
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.
45 extern boolean_t
copyin_multiple(const char *src
,
49 boolean_t
copyin_multiple(const char *src
,
54 vm_size_t first_count
;
55 boolean_t first_result
;
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.
61 assert(((vm_offset_t
)src
& 0xF0000000) !=
62 ((vm_offset_t
)(src
+ count
-1) & 0xF0000000));
64 /* TODO NMGS define sensible constants for segments, and apply
65 * to C and assembler (assembler is much harder)
67 midpoint
= (const char*) ((vm_offset_t
)(src
+ count
) & 0xF0000000);
68 first_count
= (midpoint
- src
);
70 first_result
= copyin(src
, dst
, first_count
);
72 /* If there was an error, stop now and return error */
73 if (first_result
!= 0)
76 /* otherwise finish the job and return result */
77 return copyin(midpoint
, dst
+ first_count
, count
-first_count
);
80 extern int copyout_multiple(const char *src
, char *dst
, vm_size_t count
);
82 int copyout_multiple(const char *src
, char *dst
, vm_size_t count
)
85 vm_size_t first_count
;
86 boolean_t first_result
;
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
93 assert(((vm_offset_t
)dst
& 0xF0000000) !=
94 ((vm_offset_t
)(dst
+ count
- 1) & 0xF0000000));
96 /* TODO NMGS define sensible constants for segments, and apply
97 * to C and assembler (assembler is much harder)
99 midpoint
= (char *) ((vm_offset_t
)(dst
+ count
) & 0xF0000000);
100 first_count
= (midpoint
- dst
);
102 first_result
= copyout(src
, dst
, first_count
);
104 /* If there was an error, stop now and return error */
105 if (first_result
!= 0)
108 /* otherwise finish the job and return result */
110 return copyout(src
+ first_count
, midpoint
, count
-first_count
);
130 void regDump(struct ppc_saved_state
*state
)
134 for (i
=0; i
<32; i
++) {
136 kprintf("\n%4d :",i
);
137 kprintf(" %08x",*(&state
->r0
+i
));
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
);
153 /* Be nice - for user tasks, generate some stack trace */
154 if (state
->srr1
& MASK(MSR_PR
)) {
155 char *addr
= (char*)state
->r1
;
157 for (i
= 0; i
< 8; i
++) {
158 if (addr
== (char*)NULL
)
160 if (!copyin(addr
,(char*)buf
, 2 * sizeof(int))) {
161 printf("0x%08x : %08x\n",buf
[0],buf
[1]);
162 addr
= (char*)buf
[0];
173 * invalidate_cache_for_io
175 * Takes cache of those requests which may require to flush the
176 * data cache first before invalidation.
181 invalidate_cache_for_io(vm_offset_t area
, unsigned count
, boolean_t phys
)
183 vm_offset_t aligned_start
, aligned_end
, end
;
185 /* For unaligned reads we need to flush any
186 * unaligned cache lines. We invalidate the
187 * rest as this is faster
190 aligned_start
= area
& ~(CACHE_LINE_SIZE
-1);
191 if (aligned_start
!= area
)
192 flush_dcache(aligned_start
, CACHE_LINE_SIZE
, phys
);
195 aligned_end
= (end
& ~(CACHE_LINE_SIZE
-1));
196 if (aligned_end
!= end
)
197 flush_dcache(aligned_end
, CACHE_LINE_SIZE
, phys
);
199 invalidate_dcache(area
, count
, phys
);
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
) {
208 printf("Copy in called from %08X: src=%08X; dest=%08X; lgn=%08X\n", from
, src
, dest
, lgn
);
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
) {
219 printf("Copy out called from %08X: src=%08X; dest=%08X; lgn=%08X\n", from
, src
, dest
, lgn
);
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
) {
232 printf("Copy in string called from %08X: src=%08X; dest=%08X; max=%08X; lgnadr=%08X\n",
233 from
, src
, dest
, max
, lgn
);
238 unsigned int ExceptionTrace
= 0;
239 extern void ExceptionTracePrint(struct savearea
*sv
, int type
);
240 void ExceptionTracePrint(struct savearea
*sv
, int 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]);
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]);