]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/FirmwareC.c
xnu-1228.12.14.tar.gz
[apple/xnu.git] / osfmk / ppc / FirmwareC.c
1 /*
2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * This file contains firmware code.
30 *
31 */
32
33 #include <debug.h>
34 #include <mach_vm_debug.h>
35 #include <db_machine_commands.h>
36
37 #include <kern/thread.h>
38 #include <mach/vm_attributes.h>
39 #include <mach/vm_param.h>
40 #include <kern/spl.h>
41
42 #include <kern/misc_protos.h>
43 #include <ppc/misc_protos.h>
44 #include <ppc/proc_reg.h>
45 #include <ppc/mem.h>
46 #include <ppc/pmap.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>
52
53 Boot_Video dgVideo;
54 extern GDWorkArea GratefulDebWork[];
55
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 */
60 } GDpos;
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 */
64 };
65
66 /* Window layout for Grateful Deb:
67 *
68 * 0 9
69 *
70 * 0 Total Decrimenter
71 * 1 DSI ISI
72 * 2 System call External
73 * 3 SIGP Floating point
74 * 4 Program Alignment
75 */
76
77 struct RuptCtr RuptCtrs[96] = {
78 { /* Total interruptions */
79 .GDpos = {
80 .col = 0,
81 .row = 0,
82 },
83 .count = 0,
84 .timed = 1,
85 },
86 { /* Reset */
87 .GDpos = {
88 .col = -1,
89 .row = -1,
90 },
91 .count = 0,
92 .timed = 0,
93 },
94 { /* Machine check */
95 .GDpos = {
96 .col = -1,
97 .row = -1,
98 },
99 .count = 0,
100 .timed = 0,
101 },
102 { /* DSIs */
103 .GDpos = {
104 .col = 0,
105 .row = 1,
106 },
107 .count = 0,
108 .timed = 1},
109 { /* ISIs */
110 .GDpos = {
111 .col = 1,
112 .row = 1,
113 },
114 .count = 0,
115 .timed = 1,
116 },
117 { /* Externals */
118 .GDpos = {
119 .col = 1,
120 .row = 2,
121 },
122 .count = 0,
123 .timed = 1,
124 },
125 { /* Alignment */
126 .GDpos = {
127 .col = 1,
128 .row = 4,
129 },
130 .count = 0,
131 .timed = 0,
132 },
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 */
174
175 /*Start of second processor counts */
176
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 */
225 };
226
227 void
228 GratefulDebInit(bootBumbleC *boot_video_info)
229 { /* Initialize the video debugger */
230
231 unsigned int fillframe[256];
232 unsigned int startpos, startbyte, windowleft, newwidth, i, j, startword,
233 oldwidth, nrmlgn;
234 unsigned int nwords, *byteleft, lstlgn, pixlgn, bytelgn;
235
236 if (!boot_video_info) { /* Are we disabling it? */
237 GratefulDebWork[0].GDready = 0; /* Disable output */
238 return;
239 }
240
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 */
244
245 bytelgn = (nrmlgn * (GDdispcols - 1)) + lstlgn; /* Length in bytes */
246 pixlgn = bytelgn / (boot_video_info->v_depth / 8); /* Number of pixels wide */
247
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 */
250
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 */
254
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 */
258
259 oldwidth = boot_video_info->v_width; /* Save the old width */
260 // boot_video_info->v_width = newwidth; /* Set the new width */
261
262 nwords = oldwidth - newwidth; /* See how much to fill in pixels */
263 nwords = nwords / (32 / boot_video_info->v_depth); /* Get that in bytes */
264
265 startword = (newwidth + 3) / 4; /* Where does it start? */
266
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 */
270
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 */
274
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 */
278
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 */
282
283 for (i = 0; i < nwords; i++)
284 fillframe[i] = 0xFFFFFFFF; /* Set the row to all white */
285
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 */
292 } else {
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 */
297 }
298
299 byteleft = (unsigned int *)(boot_video_info->v_baseAddr + windowleft + (boot_video_info->v_rowBytes * 2)); /* Place to start filling */
300
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 */
305 }
306
307 for (i = 0; i < 2; i++) { /* Initialize both (for now) processor areas */
308
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 +
318 (GDfontsize / 4));
319 GratefulDebWork[i].GDdepth = boot_video_info->v_depth;
320 GratefulDebWork[i].GDcollgn = nrmlgn;
321
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) */
327
328 sync();
329
330 GratefulDebWork[i].GDready = 1; /* This one's all ready */
331 }
332 }
333
334 void debugNoop(void);
335 void
336 debugNoop(void)
337 { /* This does absolutely nothing */
338 }