X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/91447636331957f3d9b5ca5b508f07c526b0074d..99c3a10404e5d1ef94397ab4df5a8b74711fc4d3:/osfmk/console/panic_dialog.c diff --git a/osfmk/console/panic_dialog.c b/osfmk/console/panic_dialog.c index 1e7a26f93..ca0acb6d1 100644 --- a/osfmk/console/panic_dialog.c +++ b/osfmk/console/panic_dialog.c @@ -1,33 +1,41 @@ /* - * 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 #include +#include #include #include #include #include #include - +#include +#include extern struct vc_info vinfo; extern boolean_t panicDialogDesired; @@ -36,17 +44,17 @@ 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; @@ -59,14 +67,16 @@ static const struct panicimage * panic_dialog = NULL; /* the active panic dialo 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') @@ -80,31 +90,29 @@ static char versionbuf[20]; /* ####.###~###\0 */ 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; @@ -115,7 +123,7 @@ panic_ui_initialize(const unsigned char * system_clut) 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; @@ -123,7 +131,7 @@ panic_ui_initialize(const unsigned char * system_clut) 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; @@ -136,7 +144,7 @@ panic_ui_initialize(const unsigned char * system_clut) } } - strcpy(versionbuf, vstr); + strlcpy(versionbuf, vstr, VERSIONBUF_LEN); } @@ -147,12 +155,11 @@ panic_dialog_test( void ) 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; @@ -189,12 +196,13 @@ draw_panic_dialog( void ) /* 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 */ @@ -224,7 +232,7 @@ draw_panic_dialog( void ) 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 ); } @@ -317,13 +325,13 @@ draw_panic_dialog( void ) /* 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]); @@ -331,13 +339,13 @@ draw_panic_dialog( void ) 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]); @@ -346,18 +354,18 @@ draw_panic_dialog( void ) 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]); @@ -393,10 +401,10 @@ panic_dialog_set_image( const unsigned char * ptr, unsigned int size ) /* 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; } @@ -407,7 +415,7 @@ panic_dialog_set_image( const unsigned char * ptr, unsigned int 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); @@ -420,7 +428,7 @@ panic_dialog_set_image( const unsigned char * ptr, unsigned int size ) */ 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; @@ -439,7 +447,7 @@ panic_dialog_verify( const struct panicimage * newimage, unsigned int 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; @@ -461,13 +469,21 @@ panic_dialog_verify( const struct panicimage * newimage, unsigned int 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 */ @@ -478,7 +494,7 @@ static unsigned char findbestgray( unsigned int color24 ); static int isActiveClutOK( void ); static int -pixels_needed_to_blit_digit( int digit ) +pixels_needed_to_blit_digit(__unused int digit ) { return FONT_WIDTH; } @@ -505,7 +521,8 @@ find_rendered_digit( int digit ) 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; @@ -517,9 +534,9 @@ blit_digit( int digit ) 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; } } @@ -530,9 +547,9 @@ blit_digit( int digit ) 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; @@ -547,6 +564,9 @@ panic_blit_rect( unsigned int x, unsigned int y, 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; } } @@ -556,15 +576,15 @@ panic_blit_rect( unsigned int x, unsigned int y, */ 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 ) @@ -598,7 +618,7 @@ panic_blit_rect_8( unsigned int x, unsigned int y, } } - dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes); + dst = (volatile unsigned char *) (((uintptr_t)dst) + vinfo.v_rowbytes); } } @@ -608,16 +628,16 @@ panic_blit_rect_8( unsigned int x, unsigned int y, * 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) + @@ -648,7 +668,7 @@ panic_blit_rect_8( unsigned int x, unsigned int y, } } - dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes); + dst = (volatile unsigned short *) (((uintptr_t)dst) + vinfo.v_rowbytes); } } @@ -658,15 +678,15 @@ panic_blit_rect_8( unsigned int x, unsigned int y, * 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 + @@ -698,10 +718,65 @@ panic_blit_rect_8( unsigned int x, unsigned int y, } } - 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: @@ -729,7 +804,8 @@ panic_blit_rect_8( unsigned int x, unsigned int y, */ 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; @@ -763,39 +839,8 @@ decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * dep } -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; @@ -813,7 +858,7 @@ strnstr(const char * s, const char * find, size_t slen) } while (strncmp(s, find, len) != 0); s--; } - return ((char *)s); + return s; } /* @@ -862,7 +907,7 @@ findbestgray( unsigned int color24 ) } /* 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 */ @@ -878,18 +923,18 @@ findbestgray( unsigned int color24 ) 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