2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * This file contains firmware code.
34 #include <mach_vm_debug.h>
35 #include <db_machine_commands.h>
37 #include <kern/thread.h>
38 #include <mach/vm_attributes.h>
39 #include <mach/vm_param.h>
42 #include <kern/misc_protos.h>
43 #include <ppc/misc_protos.h>
44 #include <ppc/proc_reg.h>
47 #include <ppc/new_screen.h>
48 #include <ppc/Firmware.h>
49 #include <ppc/mappings.h>
50 #include <pexpert/pexpert.h>
51 #include <ddb/db_output.h>
54 extern GDWorkArea GratefulDebWork
[];
56 struct RuptCtr
{ /* Counts hardware interrupts */
57 struct GDpos
{ /* Screen position for Grateful Deb display */
58 unsigned short col
; /* Column (-1 means no display) */
59 unsigned short row
; /* Row */
61 unsigned int count
; /* Count of interrupt */
62 unsigned int timed
; /* If set, count updates at timed rate */
63 unsigned int lasttime
; /* Low of timebase when last updated */
66 /* Window layout for Grateful Deb:
72 * 2 System call External
73 * 3 SIGP Floating point
77 struct RuptCtr RuptCtrs
[96] = {
78 { /* Total interruptions */
133 {.GDpos
= {.col
= 0,.row
= 4},.count
= 0,.timed
= 0}, /* Program */
134 {.GDpos
= {.col
= 1,.row
= 3},.count
= 0,.timed
= 0}, /* Floating point */
135 {.GDpos
= {.col
= 1,.row
= 0},.count
= 0,.timed
= 1}, /* Decrementer */
136 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* I/O error */
137 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
138 {.GDpos
= {.col
= 0,.row
= 2},.count
= 0,.timed
= 1}, /* System call */
139 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Trace */
140 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Floating point assist */
141 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Performance monitor */
142 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* VMX */
143 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
144 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
145 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
146 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Instruction breakpoint */
147 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* System management */
148 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
149 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
150 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
151 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
152 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
153 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
154 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
155 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
156 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
157 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
158 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
159 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Trace */
160 {.GDpos
= {.col
= 0,.row
= 3},.count
= 0,.timed
= 0}, /* SIGP */
161 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Preemption */
162 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Context switch */
163 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
164 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
165 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
166 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
167 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
168 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
169 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
170 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
171 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
172 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
173 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Special, update frequency controls */
175 /*Start of second processor counts */
177 {.GDpos
= {.col
= 0,.row
= 0},.count
= 0,.timed
= 1}, /* Total interruptions */
178 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reset */
179 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Machine check */
180 {.GDpos
= {.col
= 0,.row
= 1},.count
= 0,.timed
= 1}, /* DSIs */
181 {.GDpos
= {.col
= 1,.row
= 1},.count
= 0,.timed
= 1}, /* ISIs */
182 {.GDpos
= {.col
= 1,.row
= 2},.count
= 0,.timed
= 1}, /* Externals */
183 {.GDpos
= {.col
= 1,.row
= 4},.count
= 0,.timed
= 0}, /* Alignment */
184 {.GDpos
= {.col
= 0,.row
= 4},.count
= 0,.timed
= 0}, /* Program */
185 {.GDpos
= {.col
= 1,.row
= 3},.count
= 0,.timed
= 0}, /* Floating point */
186 {.GDpos
= {.col
= 1,.row
= 0},.count
= 0,.timed
= 1}, /* Decrementer */
187 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* I/O error */
188 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
189 {.GDpos
= {.col
= 0,.row
= 2},.count
= 0,.timed
= 1}, /* System call */
190 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Trace */
191 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Floating point assist */
192 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Performance monitor */
193 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* VMX */
194 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
195 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
196 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
197 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Instruction breakpoint */
198 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* System management */
199 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
200 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
201 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
202 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
203 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
204 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
205 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
206 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
207 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
208 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
209 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
210 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Trace */
211 {.GDpos
= {.col
= 0,.row
= 3},.count
= 0,.timed
= 0}, /* SIGP */
212 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Preemption */
213 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Context switch */
214 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
215 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
216 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
217 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
218 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
219 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
220 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
221 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
222 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
223 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Reserved */
224 {.GDpos
= {.col
= -1,.row
= -1},.count
= 0,.timed
= 0}, /* Special, update frequency controls */
228 GratefulDebInit(bootBumbleC
*boot_video_info
)
229 { /* Initialize the video debugger */
231 unsigned int fillframe
[256];
232 unsigned int startpos
, startbyte
, windowleft
, newwidth
, i
, j
, startword
,
234 unsigned int nwords
, *byteleft
, lstlgn
, pixlgn
, bytelgn
;
236 if (!boot_video_info
) { /* Are we disabling it? */
237 GratefulDebWork
[0].GDready
= 0; /* Disable output */
241 nrmlgn
= (9 * GDfontsize
) * (boot_video_info
->v_depth
/ 8); /* Get the normal column size in bytes */
242 lstlgn
= (((8 * GDfontsize
) + (GDfontsize
>> 1)) * boot_video_info
->v_depth
) / 8; /* Same as normal, but with 1/2 character space */
243 nrmlgn
= (nrmlgn
+ 31) & -32; /* Round to a line */
245 bytelgn
= (nrmlgn
* (GDdispcols
- 1)) + lstlgn
; /* Length in bytes */
246 pixlgn
= bytelgn
/ (boot_video_info
->v_depth
/ 8); /* Number of pixels wide */
248 startbyte
= (boot_video_info
->v_width
* (boot_video_info
->v_depth
/ 8)) - bytelgn
; /* Get the starting byte unaligned */
249 startpos
= boot_video_info
->v_width
- pixlgn
; /* Starting pixel position */
251 startbyte
+= (unsigned int)boot_video_info
->v_baseAddr
& 31; /* Add the extra to cache boundary in frame buffer */
252 startbyte
&= -32; /* Make sure it's on a cache line for speed */
253 startbyte
+= (unsigned int)boot_video_info
->v_baseAddr
& 31; /* Subtract the extra to cache boundary in frame buffer */
255 windowleft
= startbyte
- (((GDfontsize
/ 2) * boot_video_info
->v_depth
) / 8); /* Back up a half character */
256 windowleft
&= -4; /* Make sure it is on a word boundary */
257 newwidth
= windowleft
/ (boot_video_info
->v_depth
/ 8); /* Get the new pixel width of screen */
259 oldwidth
= boot_video_info
->v_width
; /* Save the old width */
260 // boot_video_info->v_width = newwidth; /* Set the new width */
262 nwords
= oldwidth
- newwidth
; /* See how much to fill in pixels */
263 nwords
= nwords
/ (32 / boot_video_info
->v_depth
); /* Get that in bytes */
265 startword
= (newwidth
+ 3) / 4; /* Where does it start? */
267 byteleft
= (unsigned int *)(boot_video_info
->v_baseAddr
+ windowleft
); /* Starting place */
268 for (i
= 0; i
< nwords
; i
++)
269 byteleft
[i
] = 0; /* Set the row to all black */
271 byteleft
= (unsigned int *)(boot_video_info
->v_baseAddr
+ windowleft
+ (boot_video_info
->v_rowBytes
* 1)); /* Starting place */
272 for (i
= 0; i
< nwords
; i
++)
273 byteleft
[i
] = 0; /* Set the row to all black */
275 byteleft
= (unsigned int *)(boot_video_info
->v_baseAddr
+ windowleft
+ (boot_video_info
->v_rowBytes
* (boot_video_info
->v_height
- 2))); /* Starting place */
276 for (i
= 0; i
< nwords
; i
++)
277 byteleft
[i
] = 0; /* Set the row to all black */
279 byteleft
= (unsigned int *)(boot_video_info
->v_baseAddr
+ windowleft
+ (boot_video_info
->v_rowBytes
* (boot_video_info
->v_height
- 1))); /* Starting place */
280 for (i
= 0; i
< nwords
; i
++)
281 byteleft
[i
] = 0; /* Set the row to all black */
283 for (i
= 0; i
< nwords
; i
++)
284 fillframe
[i
] = 0xFFFFFFFF; /* Set the row to all white */
286 if (boot_video_info
->v_depth
== 8) { /* See if 8 bits a pixel */
287 fillframe
[0] = 0x0000FFFF; /* Make left border */
288 fillframe
[nwords
- 1] = 0xFFFF0000; /* Make right border */
289 } else if (boot_video_info
->v_depth
== 16) { /* See if 16 bits a pixel */
290 fillframe
[0] = 0x00000000; /* Make left border */
291 fillframe
[nwords
- 1] = 0x00000000; /* Make right border */
293 fillframe
[0] = 0x00000000; /* Make left border */
294 fillframe
[1] = 0x00000000; /* Make left border */
295 fillframe
[nwords
- 1] = 0x00000000; /* Make right border */
296 fillframe
[nwords
- 2] = 0x00000000; /* Make right border */
299 byteleft
= (unsigned int *)(boot_video_info
->v_baseAddr
+ windowleft
+ (boot_video_info
->v_rowBytes
* 2)); /* Place to start filling */
301 for (i
= 2; i
< (boot_video_info
->v_height
- 2); i
++) { /* Fill the rest */
302 for (j
= 0; j
< nwords
; j
++)
303 byteleft
[j
] = fillframe
[j
]; /* Fill the row */
304 byteleft
= (unsigned int *)((unsigned int)byteleft
+ boot_video_info
->v_rowBytes
); /* Next row */
307 for (i
= 0; i
< 2; i
++) { /* Initialize both (for now) processor areas */
309 GratefulDebWork
[i
].GDtop
=
310 2 + (GDfontsize
/ 2) + (i
* 18 * GDfontsize
);
311 GratefulDebWork
[i
].GDleft
= 2 + startpos
+ (GDfontsize
/ 2);
312 GratefulDebWork
[i
].GDtopleft
=
313 boot_video_info
->v_baseAddr
+ startbyte
+
314 (GratefulDebWork
[i
].GDtop
* boot_video_info
->v_rowBytes
);
315 GratefulDebWork
[i
].GDrowbytes
= boot_video_info
->v_rowBytes
;
316 GratefulDebWork
[i
].GDrowchar
=
317 boot_video_info
->v_rowBytes
* (GDfontsize
+
319 GratefulDebWork
[i
].GDdepth
= boot_video_info
->v_depth
;
320 GratefulDebWork
[i
].GDcollgn
= nrmlgn
;
322 // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 4; /* (Update every 16th of a second (16 fps) */
323 RuptCtrs
[(48 * i
) + 47].timed
= gPEClockFrequencyInfo
.timebase_frequency_hz
>> 3; /* (Update every 8th of a second (8 fps) */
324 // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 2; /* (Update every 4th of a second (4 fps) */
325 // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 1; /* (Update every 2th of a second (2 fps) */
326 // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 0; /* (Update every 1 second (1 fps) */
330 GratefulDebWork
[i
].GDready
= 1; /* This one's all ready */
334 void debugNoop(void);
337 { /* This does absolutely nothing */