/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#include <vc.h>
#include <console/video_console.h>
+#include <libkern/OSByteOrder.h>
#include <kdp/kdp_udp.h>
#include <kern/debug.h>
#include <mach/mach_time.h>
#include <sys/errno.h>
#include <string.h>
-
+#include <machine/machlimits.h>
+#include <pexpert/pexpert.h>
extern struct vc_info vinfo;
extern boolean_t panicDialogDesired;
void panic_ui_initialize(const unsigned char * system_clut);
int panic_dialog_set_image( const unsigned char * ptr, unsigned int size );
-void panic_dialog_get_image( unsigned char ** ptr, unsigned int * size );
+void panic_dialog_get_image(const unsigned char **ptr, unsigned int *size);
void draw_panic_dialog( void );
void panic_dialog_test( void );
static int panic_dialog_verify( const struct panicimage * data, unsigned int size );
static int pixels_needed_to_blit_digit( int digit );
static void blit_digit( int digit );
-static char * strnstr(const char * s, const char * find, size_t slen);
-static void dim_screen(void);
-static void panic_blit_rect(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr );
+static const char * strnstr(const char * s, const char * find, size_t slen);
+static void panic_blit_rect(unsigned int x, unsigned int y, unsigned int width,
+ unsigned int height, int transparent,
+ const unsigned char * dataPtr);
static int panic_info_x;
static int panic_info_y;
static const unsigned char * panic_dialog_data = NULL; /* where the image data starts */
static const unsigned char * panic_dialog_clut = NULL; /* where the clut used for the image starts */
-static unsigned char * curr_image_ptr = NULL; /* If NULL, the default panic dialog is active */
+static const unsigned char *curr_image_ptr; /* If NULL, the default panic
+ dialog is active */
static unsigned int curr_image_size = 0;
#define FONT_WIDTH 8
#define FONT_HEIGHT 16
static unsigned short rendered_font[FONT_HEIGHT][FONT_WIDTH];
-static char versionbuf[20]; /* ####.###~###\0 */
+#define VERSIONBUF_LEN 20
+static char versionbuf[VERSIONBUF_LEN]; /* ####.###~###\0 */
#define isdigit(d) ((d) >= '0' && (d) <= '9')
extern unsigned char iso_font[];
extern const char version[];
-extern unsigned int panic_caller;
void
panic_ui_initialize(const unsigned char * system_clut)
{
- char vstr[20];
-
+ char vstr[VERSIONBUF_LEN];
panic_dialog_set_image( NULL, 0 );
active_clut = system_clut;
- strcpy(vstr, "custom");
+ strlcpy(vstr, "custom", VERSIONBUF_LEN);
/* Convert xnu-####.###.obj~### into ####.###~### */
- if (version) {
- char * versionpos = strnstr(version, "xnu-", 20);
+ if (version[0]) {
+ const char *versionpos = strnstr(version, "xnu-", VERSIONBUF_LEN);
if (versionpos) {
int len, i;
vstr[0] = '\0';
- for (i=0,len=4;len<20;len++) {
+ for (i = 0, len = 4; len < VERSIONBUF_LEN; len++) {
if (isdigit(versionpos[len]) || versionpos[len] == '.') { /* extract ####.###. */
vstr[i++] = versionpos[len];
continue;
if ( versionpos[len-1] == '.' ) /* remove trailing period if present */
i--;
- for (;len<20;len++) { /* skip to next digit if present */
+ for (; len < VERSIONBUF_LEN; len++) { /* skip to next digit if present */
if ( !isdigit(versionpos[len]) )
continue;
break;
if ( versionpos[len-1] == '~' ) { /* extract ~### if present */
vstr[i++] = versionpos[len-1];
- for (;len<20;len++) { /* extract ### */
+ for (; len < VERSIONBUF_LEN; len++) { /* extract ### */
if ( isdigit(versionpos[len]) ) {
vstr[i++] = versionpos[len];
continue;
}
}
- strcpy(versionbuf, vstr);
+ strlcpy(versionbuf, vstr, VERSIONBUF_LEN);
}
boolean_t o_panicDialogDrawn = panicDialogDrawn;
boolean_t o_panicDialogDesired = panicDialogDesired;
unsigned int o_logPanicDataToScreen = logPanicDataToScreen;
- unsigned int o_panic_caller = panic_caller;
+ unsigned long o_panic_caller = panic_caller;
unsigned int o_panicDebugging = panicDebugging;
-
panicDebugging = TRUE;
- panic_caller = (unsigned int) __builtin_return_address(0);
+ panic_caller = (unsigned long)(char *)__builtin_return_address(0);
logPanicDataToScreen = FALSE;
panicDialogDesired = TRUE;
panicDialogDrawn = FALSE;
/* set up to draw background box */
/* by locating where the upper left corner is placed */
- pd_x = (vinfo.v_width/2) - panic_dialog->pd_width/2;
- pd_y = (vinfo.v_height/2) - panic_dialog->pd_height/2;
+ pd_x = (int)((vinfo.v_width/2) - panic_dialog->pd_width/2);
+ pd_y = (int)((vinfo.v_height/2) - panic_dialog->pd_height/2);
/* draw panic dialog at pd_x/pd_y */
- panic_blit_rect( pd_x, pd_y, panic_dialog->pd_width, panic_dialog->pd_height,
- 0, (unsigned char*) panic_dialog_data);
+ panic_blit_rect(pd_x, pd_y, panic_dialog->pd_width,
+ panic_dialog->pd_height, 0,
+ panic_dialog_data);
panic_dialog_count = 0; /* number of info items to display at the bottom of dialog */
panic_dialog_info[panic_dialog_count].pixels += pixels_needed_to_blit_digit( ':' );
for ( count=8; count != 0; count-- ) {
- nibble = (panic_caller >> ((count-1)<<2)) &0xF;
+ nibble = (int)((panic_caller >> ((count-1)<<2)) &0xF);
panic_num_chars[indx++] = nibble;
panic_dialog_info[panic_dialog_count].pixels += pixels_needed_to_blit_digit( nibble );
}
/* vertical alignment for information to be displayed */
- panic_info_y = (vinfo.v_height/2) + panic_dialog->pd_height/2 - (panic_dialog->pd_info_height);
+ panic_info_y = (int)((vinfo.v_height/2) + panic_dialog->pd_height/2 - (panic_dialog->pd_info_height));
/* blit out all the information we gathered */
switch ( panic_dialog_count ) {
case 1 : /* one item is centered */
- panic_info_x = (vinfo.v_width/2) - (panic_dialog_info[0].pixels/2);
+ panic_info_x = (int)((vinfo.v_width/2) - (panic_dialog_info[0].pixels/2));
for (indx=1; indx < panic_dialog_info[0].chars[0]; indx++)
blit_digit(panic_dialog_info[0].chars[indx]);
case 2 : /* left centered and right centered */
x1 = ((panic_dialog->pd_width/2) - panic_dialog_info[0].pixels)/2;
- panic_info_x = ((vinfo.v_width/2) - (panic_dialog->pd_width/2)) + x1;
+ panic_info_x = (int)(((vinfo.v_width/2) - (panic_dialog->pd_width/2)) + x1);
for (indx=1; indx < panic_dialog_info[0].chars[0]; indx++)
blit_digit(panic_dialog_info[0].chars[indx]);
x2 = ((panic_dialog->pd_width/2) - panic_dialog_info[1].pixels)/2;
- panic_info_x = (vinfo.v_width/2) + x2;
+ panic_info_x = (int)((vinfo.v_width/2) + x2);
for (indx=1; indx < panic_dialog_info[1].chars[0]; indx++)
blit_digit(panic_dialog_info[1].chars[indx]);
case 3 : /* left centered, middle and right centered */
x1 = ((panic_dialog->pd_width/2) - panic_dialog_info[0].pixels - (panic_dialog_info[1].pixels/2))/2;
- panic_info_x = ((vinfo.v_width/2) - (panic_dialog->pd_width/2)) + x1;
+ panic_info_x = (int)(((vinfo.v_width/2) - (panic_dialog->pd_width/2)) + x1);
for (indx=1; indx < panic_dialog_info[0].chars[0]; indx++)
blit_digit(panic_dialog_info[0].chars[indx]);
- panic_info_x = (vinfo.v_width/2) - (panic_dialog_info[1].pixels/2);
+ panic_info_x = (int)((vinfo.v_width/2) - (panic_dialog_info[1].pixels/2));
for (indx=1; indx < panic_dialog_info[1].chars[0]; indx++)
blit_digit(panic_dialog_info[1].chars[indx]);
x2 = ((panic_dialog->pd_width/2) - panic_dialog_info[2].pixels - (panic_dialog_info[1].pixels/2))/2;
- panic_info_x = (vinfo.v_width/2) + x2 + (panic_dialog_info[1].pixels/2);
+ panic_info_x = (int)((vinfo.v_width/2) + x2 + (panic_dialog_info[1].pixels/2));
for (indx=1; indx < panic_dialog_info[2].chars[0]; indx++)
blit_digit(panic_dialog_info[2].chars[indx]);
/* if ptr is NULL, restore panic image to built-in default */
if ( ptr == NULL ) {
newimage = &panic_dialog_default;
- newsize = sizeof(struct panicimage) + newimage->pd_dataSize;
+ newsize = (unsigned int)(sizeof(struct panicimage) + newimage->pd_dataSize);
}
else {
- newimage = (struct panicimage *) ptr;
+ newimage = (const struct panicimage *)ptr;
newsize = size;
}
panic_dialog_data = &panic_dialog->data[0];
panic_dialog_clut = &panic_dialog->data[panic_dialog->pd_dataSize-CLUT_SIZE];
- curr_image_ptr = (unsigned char *) ptr;
+ curr_image_ptr = ptr;
curr_image_size = size;
return (0);
*/
void
-panic_dialog_get_image( unsigned char ** ptr, unsigned int * size )
+panic_dialog_get_image(const unsigned char ** ptr, unsigned int * size )
{
*ptr = curr_image_ptr;
*size = curr_image_size;
if ( size < (sizeof(struct panicimage) + newimage->pd_dataSize) )
return EINVAL;
- if ( newimage->pd_tag != 'RNMp' )
+ if ( newimage->pd_tag != 0x524E4D70 /* 'RNMp' */ )
return EINVAL;
size = newimage->pd_dataSize-CLUT_SIZE;
static const struct rendered_num * find_rendered_digit( int digit );
-static void panic_blit_rect_8( unsigned int x, unsigned int y, unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr );
-static void panic_blit_rect_16( unsigned int x, unsigned int y, unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr );
-static void panic_blit_rect_32( unsigned int x, unsigned int y, unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr );
-static int decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * depth, unsigned char ** value );
+static void panic_blit_rect_8(unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height,
+ int transparent, const unsigned char *dataPtr);
+static void panic_blit_rect_16(unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height,
+ int transparent, const unsigned char *dataPtr);
+static void panic_blit_rect_32(unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height,
+ int transparent, const unsigned char *dataPtr);
+static void panic_blit_rect_30(unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height,
+ int transparent, const unsigned char *dataPtr);
+static int decode_rle(const unsigned char *dataPtr,
+ unsigned int *quantity, unsigned int *depth,
+ const unsigned char **value);
/* Utilities to convert 8 bit/gray */
static int isActiveClutOK( void );
static int
-pixels_needed_to_blit_digit( int digit )
+pixels_needed_to_blit_digit(__unused int digit )
{
return FONT_WIDTH;
}
static void
blit_digit( int digit )
{
- unsigned char * raw_data = (unsigned char *) find_rendered_digit( digit );
+ const unsigned char *raw_data =
+ (const unsigned char *)find_rendered_digit(digit);
unsigned width = FONT_WIDTH, height = FONT_HEIGHT;
int row;
for( j=FONT_WIDTH-1; j>=0; j--) {
if ( bits & 0x80 )
- rendered_font[row][j] = 0x0100 | panic_dialog->pd_info_color[0];
+ rendered_font[row][j] = OSSwapBigToHostInt16(0x0100 | panic_dialog->pd_info_color[0]);
else
- rendered_font[row][j] = 0x0100 | panic_dialog->pd_info_color[1];
+ rendered_font[row][j] = OSSwapBigToHostInt16(0x0100 | panic_dialog->pd_info_color[1]);
bits <<= 1;
}
}
static void
-panic_blit_rect( unsigned int x, unsigned int y,
- unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr )
+panic_blit_rect(unsigned int x, unsigned int y, unsigned int width,
+ unsigned int height, int transparent,
+ const unsigned char *dataPtr)
{
if(!vinfo.v_depth)
return;
case 32:
panic_blit_rect_32( x, y, width, height, transparent, dataPtr);
break;
+ case 30:
+ panic_blit_rect_30( x, y, width, height, transparent, dataPtr);
+ break;
}
}
*/
static void
-panic_blit_rect_8( unsigned int x, unsigned int y,
- unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr )
+panic_blit_rect_8(unsigned int x, unsigned int y, unsigned int width,
+ unsigned int height, __unused int transparent,
+ const unsigned char * dataPtr)
{
volatile unsigned char * dst;
unsigned int line, col, i;
static int clutOK = -1;
unsigned int data, quantity, depth;
- unsigned char * value;
+ const unsigned char *value;
if ( clutOK == -1 )
}
}
- dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
+ dst = (volatile unsigned char *) (((uintptr_t)dst) + vinfo.v_rowbytes);
}
}
* pixel values (RGB) and writes each pixel to the screen.
*/
- static void
- panic_blit_rect_16( unsigned int x, unsigned int y,
- unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr )
- {
+static void
+panic_blit_rect_16(unsigned int x, unsigned int y, unsigned int width,
+ unsigned int height, __unused int transparent,
+ const unsigned char *dataPtr)
+{
volatile unsigned short * dst;
unsigned int line, col, i;
unsigned int quantity, index, data, depth;
- unsigned char * value;
+ const unsigned char *value;
dst = (volatile unsigned short *) (vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
}
}
- dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
+ dst = (volatile unsigned short *) (((uintptr_t)dst) + vinfo.v_rowbytes);
}
}
* writes it to the screen.
*/
- static void
- panic_blit_rect_32( unsigned int x, unsigned int y,
- unsigned int width, unsigned int height,
- int transparent, unsigned char * dataPtr )
- {
+static void
+panic_blit_rect_32(unsigned int x, unsigned int y, unsigned int width,
+ unsigned int height, __unused int transparent,
+ const unsigned char *dataPtr)
+{
volatile unsigned int * dst;
unsigned int line, col, i;
unsigned int quantity, index, data, depth;
- unsigned char * value;
+ const unsigned char *value;
dst = (volatile unsigned int *) (vinfo.v_baseaddr +
}
}
- dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
+ dst = (volatile unsigned int *) (((uintptr_t)dst) + vinfo.v_rowbytes);
}
}
+/*
+ * panic_blit_rect_30 decodes the RLE encoded image data on the fly, and fills
+ * in each of the three pixel values from the clut (RGB) for each pixel and
+ * writes it to the screen.
+ */
+
+static void
+panic_blit_rect_30(unsigned int x, unsigned int y, unsigned int width,
+ unsigned int height, __unused int transparent,
+ const unsigned char *dataPtr)
+{
+ volatile unsigned int * dst;
+ unsigned int line, col, i;
+ unsigned int quantity, index, data, depth;
+ const unsigned char *value;
+ unsigned int in;
+
+ dst = (volatile unsigned int *) (vinfo.v_baseaddr +
+ (y * vinfo.v_rowbytes) +
+ (x * 4));
+
+ quantity = 0;
+ i = 0;
+
+ for( line = 0; line < height; line++) {
+ for( col = 0; col < width; col++) {
+
+ if (quantity == 0) {
+ dataPtr += decode_rle(dataPtr, &quantity, &depth, &value);
+ i = 0;
+ }
+
+ index = value[i++] * 3;
+ in = panic_dialog_clut[index + 0];
+ data = (in << 2) | (in >> 6);
+
+ in = panic_dialog_clut[index + 1];
+ data |= (in << (2 + 10)) | ((3 << 10) & (in << 4));
+
+ in = panic_dialog_clut[index + 2];
+ data |= (in << (2 + 20)) | ((3 << 20) & (in << 14));
+
+ *(dst + col) = data;
+
+ if ( i == depth ) {
+ i = 0;
+ quantity--;
+ }
+ }
+
+ dst = (volatile unsigned int *) (((uintptr_t)dst) + vinfo.v_rowbytes);
+ }
+}
+
+
/*
decode_rle decodes a single quantity/value run of a "modified-RLE" encoded
image. The encoding works as follows:
*/
static int
-decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * depth, unsigned char ** value )
+decode_rle(const unsigned char *dataPtr, unsigned int *quantity,
+ unsigned int *depth, const unsigned char **value )
{
unsigned int mask;
int i, runlen, runsize;
}
-static void
-dim_screen(void)
-{
- unsigned long *p, *endp, *row;
- int col, rowline, rowlongs;
- register unsigned long mask;
-
- if(!vinfo.v_depth)
- return;
-
- if ( vinfo.v_depth == 32 )
- mask = 0x007F7F7F;
- else if ( vinfo.v_depth == 16 )
- mask = 0x3DEF3DEF;
- else
- return;
-
- rowline = vinfo.v_rowscanbytes / 4;
- rowlongs = vinfo.v_rowbytes / 4;
-
- p = (unsigned long*) vinfo.v_baseaddr;
- endp = p + (rowlongs * vinfo.v_height);
-
- for (row = p ; row < endp ; row += rowlongs) {
- for (p = &row[0], col = 0; col < rowline; col++) {
- *p++ = (*p >> 1) & mask;
- }
- }
-}
-
-
/* From user mode Libc - this ought to be in a library */
-static char *
+static const char *
strnstr(const char * s, const char * find, size_t slen)
{
char c, sc;
} while (strncmp(s, find, len) != 0);
s--;
}
- return ((char *)s);
+ return s;
}
/*
}
/* Did we fail to find any grays ? */
- if ( bestindex == -1 ) {
+ if (ULONG_MAX == bestindex) {
/* someday we should look for the best color match */
/* but for now just return the gray as the index */
/* at least there might be something readble on the display */
static unsigned char
color24togray8( unsigned int color24 )
{
- float R, G, B;
- float Gray;
+ int R, G, B;
+ int Gray;
unsigned char gray8;
R = (color24 & 0xFF0000) >> 16 ;
G = (color24 & 0xFF00) >> 8 ;
B = (color24 & 0xFF);
- Gray = (R*.30) + (G*.59) + (B*.11);
- gray8 = (unsigned char) ( Gray + .5);
+ Gray = (R*30) + (G*59) + (B*11);
+ gray8 = (unsigned char) ((Gray + 50) / 100);
return gray8;
-}
+}
static unsigned char