]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/console/panic_dialog.c
xnu-1456.1.26.tar.gz
[apple/xnu.git] / osfmk / console / panic_dialog.c
index cad977f8a523f64fa121978840854453e85f9f1d..29fa14890254216eb551ba9362fb28f2c2ecb0ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -34,7 +34,7 @@
 #include <mach/mach_time.h>
 #include <sys/errno.h>
 #include <string.h>
-
+#include <machine/machlimits.h>
 
 extern struct vc_info vinfo;
 extern boolean_t panicDialogDesired;
@@ -43,17 +43,18 @@ 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);
+void dim_screen(void);
+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;
@@ -66,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')
 
@@ -87,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;
@@ -122,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;
@@ -130,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;
@@ -143,7 +144,7 @@ panic_ui_initialize(const unsigned char * system_clut)
                }
        }
 
-       strcpy(versionbuf, vstr);
+       strlcpy(versionbuf, vstr, VERSIONBUF_LEN);
 }
 
 
@@ -154,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;
@@ -196,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 */
 
@@ -231,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 );
                                        }
@@ -324,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]);
 
@@ -338,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]);
@@ -353,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]);
@@ -400,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;
        }
 
@@ -414,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);
@@ -427,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;
@@ -446,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;
@@ -468,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 */
@@ -485,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;
 }
@@ -512,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;
 
@@ -537,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;
@@ -554,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;
     }
 }
 
@@ -563,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 )
@@ -605,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);
        }
 }
 
@@ -615,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) +
@@ -655,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);
        }
  }
 
@@ -665,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 +
@@ -705,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:
@@ -736,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;
@@ -770,39 +839,42 @@ decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * dep
 }
 
 
-static void 
+void 
 dim_screen(void)
 {
-       unsigned long *p, *endp, *row;
+       unsigned int *p, *endp, *row;
        int      col, rowline, rowlongs;
-       register unsigned long mask;
+       register unsigned int mask;
 
        if(!vinfo.v_depth)
                return;
 
        if ( vinfo.v_depth == 32 )
                mask = 0x007F7F7F;
+       else if ( vinfo.v_depth == 30 )
+               mask = (0x1ff<<20) | (0x1ff<<10) | 0x1ff;
        else if ( vinfo.v_depth == 16 )
                mask = 0x3DEF3DEF;
        else
                return;
 
-       rowline = vinfo.v_rowscanbytes / 4;
-       rowlongs = vinfo.v_rowbytes / 4;
+       rowline = (int)(vinfo.v_rowscanbytes / 4);
+       rowlongs = (int)(vinfo.v_rowbytes / 4);
 
-       p = (unsigned long*) vinfo.v_baseaddr;
+       p = (unsigned int*) 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;
+                       *p = (*p >> 1) & mask;
+                       ++p;
                }
        }
 }
 
 
 /* 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;
@@ -820,7 +892,7 @@ strnstr(const char * s, const char * find, size_t slen)
     } while (strncmp(s, find, len) != 0);
     s--; 
   }       
-  return ((char *)s);
+  return s;
 } 
 
 /*
@@ -869,7 +941,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 */
@@ -896,7 +968,7 @@ color24togray8( unsigned int color24 )
     Gray = (R*30) + (G*59) + (B*11);
     gray8 = (unsigned char) ((Gray + 50) / 100);
     return gray8;
-}       
+}
 
 
 static unsigned char