[haiku-development] Re: App server hangs at boot

  • From: Gerald Zajac <zajacg@xxxxxxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Fri, 19 Oct 2007 17:46:50 -0400

Antti Soininen wrote:
The code in the accelerant which detects the size of an LCD display on a
notebook computer seems to work fine on T23 computers which have a
SuperSavage chipset.  Does the log always show a size of 1408 x 1050?

In what situation the Haiku log wouldn't show that size? Before I could
get any serial output I tried several combinations of safe mode options,
which all led to gdb. The safe mode video mode 1400x1050 shows Haiku
boot screen and gdb in my native resolution, though.

X.org driver reports the same LCD size 1408x1050 (the Haiku driver is
just a rework of the xorg driver...), but works fine here (in Linux,
that is).

Attached is a diff file with changes to the S3 Savage video accelerant which should fix this problem. In addition to this fix, a few other changes have been made to the accelerant which are:

1) Some video modes which did not work properly with the Savage chips have been removed from the mode list, and a few wide-screen modes which work have been added.

2) The code which loads the cursor image has been simplified. This code is similar to the code I'm using in the S3 Virge video driver which I will be submitting to the Haiku project in a few days. This change also removes the last piece of code that came from Erdi Chen's BeSavage driver; thus, this diff file also removes his copyright from the file savage_cursor.c.

Gerald Zajac



Index: src/add-ons/accelerants/s3savage/savage_cursor.c
===================================================================
--- src/add-ons/accelerants/s3savage/savage_cursor.c    (revision 22622)
+++ src/add-ons/accelerants/s3savage/savage_cursor.c    (working copy)
@@ -1,8 +1,6 @@
 /*
-       Haiku S3 Savage driver adapted from the original BeSavage driver by
-       Erdi Chen and the X.org Savage driver.
+       Haiku S3 Savage driver adapted from the X.org Savage driver.
 
-       Copyright 1999  Erdi Chen
        Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
        Copyright (c) 2003-2006, X.Org Foundation
 
@@ -101,7 +99,7 @@
 }
 
 
-void 
+static void 
 SavageSetCursorColors(int bg, int fg)
 {
        /* With the streams engine on HW Cursor seems to be 24bpp ALWAYS */
@@ -127,74 +125,44 @@
 /* Assume width and height are byte-aligned. */
 
 bool 
-SavageLoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask)
+SavageLoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
 {
-       int i, x, y, bit_shift;
-       uint8 and_buf[64*64 / 8];
-       uint8 xor_buf[64*64 / 8];
-       uint8* and_ptr = and_mask;
-       uint8* xor_ptr = xor_mask;
-       uint16* pFB;
+       int i, colByte, row;
+       uint8*  fbCursor;
+       uint16* fbCursor16;
 
-//@    TRACE(("SavageLoadCursorImage\n"));
+//     TRACE(("SavageLoadCursorImage, width: %ld  height: %ld\n", width, 
height));
 
-       if ( ! and_mask || ! xor_mask)
+       if ( ! andMask || ! xorMask)
                return false;
 
-       bit_shift = width & 7;
-       width /= 8;
-
-       if (width != 64 || height != 64) {
-               and_ptr = (uint8*)and_buf;
-               xor_ptr = (uint8*)xor_buf;
-
-               for (y = 0; y < height; y++) {
-                       for (x = 0; x < width; x++) {
-                               *and_ptr++ = *and_mask++;
-                               *xor_ptr++ = *xor_mask++;
-                       }
-
-                       if (bit_shift) {
-                               x++;
-                               *and_ptr++ = 0xFF ^ ((*and_mask++) & (~(0xFF >> 
bit_shift)));
-                               *xor_ptr++ = (*xor_mask++) & (~(0xFF >> 
bit_shift));
-                       }
-
-                       for (; x < 8; x++) {
-                               *and_ptr++ = 0xFF;
-                               *xor_ptr++ = 0x00;
-                       }
+       // Initialize the hardware cursor as completely transparent.
+       
+       fbCursor16 = (void *)((addr_t)si->videoMemAddr + si->cursorOffset);
+       
+       for (i = 0; i < 1024 / 4; i++) {
+               *fbCursor16++ = ~0;             // and bits
+               *fbCursor16++ = 0;              // xor bits
+       }
+       
+       // Now load the AND & XOR masks for the cursor image into the cursor
+       // buffer.
+       
+       fbCursor = (void *)((addr_t)si->videoMemAddr + si->cursorOffset);
+       
+       for (row = 0; row < height; row++) {
+               for (colByte = 0; colByte < width / 8; colByte++) {
+                       fbCursor[row * 16 + colByte] = *andMask++;
+                       fbCursor[row * 16 + colByte + 2] = *xorMask++;
                }
-
-               for (; y < 64; y++) {
-                       *(uint32 *)and_ptr = ~0;
-                       and_ptr += 4;
-                       *(uint32 *)and_ptr = ~0;
-                       and_ptr += 4;
-                       *(uint32 *)xor_ptr = 0;
-                       xor_ptr += 4;
-                       *(uint32 *)xor_ptr = 0;
-                       xor_ptr += 4;
-               }
-
-               and_ptr = (uint8 *)and_buf;
-               xor_ptr = (uint8 *)xor_buf;
        }
+       
+       SavageSetCursorColors(~0, 0);   // set cursor colors to black & white
 
        /* Set cursor location in video memory.  */
        WriteCrtc(0x4d, (0xff & si->cursorOffset / 1024));
        WriteCrtc(0x4c, (0xff00 & si->cursorOffset / 1024) >> 8);
 
-       pFB = (void *)((addr_t)si->videoMemAddr + si->cursorOffset);
-
-       for (i = 0; i < 64 * 64 / 16; i++) {
-               *pFB++ = *(uint16*)and_ptr;
-               *pFB++ = *(uint16*)xor_ptr;
-
-               and_ptr += 2;
-               xor_ptr += 2;
-       }
-
        if (S3_SAVAGE4_SERIES(si->chipset)) {
                /*
                 * Bug in Savage4 Rev B requires us to do an MMIO read after
Index: src/add-ons/accelerants/s3savage/savage.h
===================================================================
--- src/add-ons/accelerants/s3savage/savage.h   (revision 22622)
+++ src/add-ons/accelerants/s3savage/savage.h   (working copy)
@@ -245,8 +245,9 @@
 
 
 
+bool IsDisplaySizeValid(int width, int height);
+
 bool SavageLoadCursorImage(int width, int height, uint8* and_mask, uint8* 
xor_mask);
-void SavageSetCursorColors(int bg, int fg);
 void SavageSetCursorPosition(int x, int y);
 void SavageShowCursor(void);
 void SavageHideCursor(void);
Index: src/add-ons/accelerants/s3savage/savage_driver.c
===================================================================
--- src/add-ons/accelerants/s3savage/savage_driver.c    (revision 22622)
+++ src/add-ons/accelerants/s3savage/savage_driver.c    (working copy)
@@ -189,7 +189,8 @@
 }
 
 
-static void SavageGetPanelInfo()
+static void
+SavageGetPanelInfo()
 {
        uint8 cr6b;
        int panelX, panelY;
@@ -209,15 +210,21 @@
        panelX = (ReadSeq(0x61) + ((ReadSeq(0x66) & 0x02) << 7) + 1) * 8;
        panelY =  ReadSeq(0x69) + ((ReadSeq(0x6e) & 0x70) << 4) + 1;
 
-       /* OK, I admit it.  I don't know how to limit the max dot clock
-        * for LCD panels of various sizes.  I thought I copied the formula
-        * from the BIOS, but many users have informed me of my folly.
-        *
-        * Instead, I'll abandon any attempt to automatically limit the
-        * clock, and add an LCDClock option to XF86Config.  Some day,
-        * I should come back to this.
-        */
+       if ( ! IsDisplaySizeValid(panelX, panelY)) {
+               
+               // Some chips such as the Savage IX/MV in a Thinkpad T-22 will 
return
+               // a width that is 8 pixels too wide probably because reg SR61 
is set
+               // to a value +1 higher than it should be.  Subtract 8 from the 
width,
+               // and check if that is a valid width.
 
+               panelX -= 8;
+               if ( ! IsDisplaySizeValid(panelX, panelY)) {
+                       TRACE(("%dx%d LCD panel size invalid.  No matching 
video mode\n", panelX + 8, panelY));
+                       si->displayType = MT_CRT;
+                       return;
+               }
+       }
+
        if ((ReadSeq(0x39) & 0x03) == 0)
                sTechnology = "TFT";
        else if ((ReadSeq(0x30) & 0x01) == 0)
@@ -229,7 +236,7 @@
                         cr6b & ActiveLCD ? "and active" : "but not active"));
 
        if (cr6b & ActiveLCD) {
-               TRACE(("Limiting video mode to %dx%d\n", panelX, panelY));
+               TRACE(("Limiting max video mode to %dx%d\n", panelX, panelY));
 
                si->panelX = panelX;
                si->panelY = panelY;
Index: src/add-ons/accelerants/s3savage/ProposeDisplayMode.c
===================================================================
--- src/add-ons/accelerants/s3savage/ProposeDisplayMode.c       (revision 22622)
+++ src/add-ons/accelerants/s3savage/ProposeDisplayMode.c       (working copy)
@@ -17,8 +17,6 @@
 
 static const display_mode mode_list[] = {
        { { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 
480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */
-       { { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 
480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */
-       { { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 
480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */
        { { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 
480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */
        { { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 
480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */
        { { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 
480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */
@@ -35,6 +33,7 @@
        { { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, 
T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@75Hz_(1024X768X8.Z1) */
        { { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, 
T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@85Hz_(1024X768X8.Z1) */
 
+       { { 81642, 1152, 1216, 1336, 1520, 864, 865, 868, 895, 
T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, // 1152x864x60Hz
        { { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, 
T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
        { { 97800, 1152, 1216, 1344, 1552, 864, 865, 868, 900, 
T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
        { { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, 
T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@75Hz_(1152X864X8.Z1) */
@@ -59,14 +58,13 @@
 
        { { 218250, 1856, 1952, 2176, 2528, 1392, 1393, 1396, 1439, 
B_POSITIVE_VSYNC}, B_CMAP8, 1856, 1392, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@60Hz_(1856X1392) */
        { { 288000, 1856, 1984, 2208, 2560, 1392, 1393, 1396, 1500, 
B_POSITIVE_VSYNC}, B_CMAP8, 1856, 1392, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@75Hz_(1856X1392) */
+       
+       // widescreen resolutions, 16:10
+       { { 83500, 1280, 1344, 1480, 1680, 800, 801, 804, 828, 
T_POSITIVE_SYNC}, B_CMAP8, 1280, 800, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@60Hz_(1280X800) */
+       { { 106500, 1440, 1520, 1672, 1904, 900, 901, 904, 932, 
T_POSITIVE_SYNC}, B_CMAP8, 1440, 900, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@60Hz_(1440X900) */
 
-       { { 234000, 1920, 2048, 2256, 2600, 1440, 1441, 1444, 1500, 
B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@60Hz_(1920X1440) */
-       { { 297000, 1920, 2064, 2288, 2640, 1440, 1441, 1444, 1500, 
B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@75Hz_(1920X1440) */
-       { { 341350, 1920, 2072, 2288, 2656, 1440, 1441, 1444, 1512, 
B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@85Hz_(1920X1440) */
-
-       { { 266950, 2048, 2200, 2424, 2800, 1536, 1537, 1540, 1589, 
B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@60Hz_(2048x1536) */
-       { { 340480, 2048, 2216, 2440, 2832, 1536, 1537, 1540, 1603, 
B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}, /* 
Vesa_Monitor_@75Hz_(2048x1536) */
-       { { 388040, 2048, 2216, 2440, 2832, 1536, 1537, 1540, 1612, 
B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}  /* 
Vesa_Monitor_@85Hz_(2048x1536) */
+       // widescreen resolutions, 16:9
+       { { 74520, 1280, 1368, 1424, 1656, 720, 724, 730, 750, 
T_POSITIVE_SYNC}, B_CMAP8, 1280, 720, 0, 0, MODE_FLAGS} /* 
Vesa_Monitor_@60Hz_(1280X720) */
 };
 
 
@@ -213,12 +211,13 @@
                result = B_BAD_VALUE;
        
        // If the video is connected directly to an LCD display (ie, notebook
-       // computer), restrict the display mode to the resolution of the LCD
-       // display.
+       // computer), restrict the display mode to resolutions where the width 
and
+       // height of the mode are less than or equal to the width and height of 
the
+       // LCD display.
        
        if (MT_LCD == si->displayType && si->panelX > 0 && si->panelY > 0 &&
-               (target->timing.h_display != si->panelX
-                       || target->timing.v_display != si->panelY)) {
+               (target->timing.h_display > si->panelX
+                       || target->timing.v_display > si->panelY)) {
                return B_ERROR;
        }
 
@@ -399,3 +398,19 @@
        return B_OK;
 }
 
+
+bool
+IsDisplaySizeValid(int width, int height)
+{
+       // Search the mode list for a mode which has the width and height passed
+       // by the caller, and return true if a match is found.
+
+       uint32 i;
+       
+       for (i = 0; i < MODE_COUNT; i++) {
+               if (mode_list[i].virtual_width == width && 
mode_list[i].virtual_height == height)
+                       return true;
+       }
+       
+       return false;           // match not found
+}
Index: src/add-ons/accelerants/s3savage/InitAccelerant.c
===================================================================
--- src/add-ons/accelerants/s3savage/InitAccelerant.c   (revision 22622)
+++ src/add-ons/accelerants/s3savage/InitAccelerant.c   (working copy)
@@ -142,10 +142,6 @@
        /* count of issued parameters or commands */
        si->engine.lastIdle = si->engine.count = 0;
 
-       /* set the cursor colors.       You may or may not have to do this, 
depending
-       on the device. */
-       SavageSetCursorColors(~0, 0);
-
        /* ensure cursor state */
        SHOW_CURSOR(false);
 

Other related posts: