dong Posted August 20, 2008 Share Posted August 20, 2008 Your log shows that all information can be fetched from BIOS or injected without problem. Now comes the real issue, how to use them to drive the card in OSX. Link to comment Share on other sites More sharing options...
Slice Posted August 20, 2008 Author Share Posted August 20, 2008 Your log shows that all information can be fetched from BIOS or injected without problem. Now comes the real issue, how to use them to drive the card in OSX. My real issue is step before. I have mixture of sources with different structures struct fb_var_screeninfo { ... struct fb_videomode { ... typedef struct _ScrnInfoRec { .... /* Video mode */ typedef struct _DisplayModeRec { Old procedures work fine with old structures and new with new. When I resolve all contradictions I begin to study how to drive the card. Next week I am going to vacancy and will be absent up to middle of september. Hope you will have some success during the time. Link to comment Share on other sites More sharing options...
Slice Posted August 22, 2008 Author Share Posted August 22, 2008 I probably found new problem. The linux sources adjust different radeon registers for different monitor output switch(radeon_output->MonType) { case MT_LCD: ErrorF("restore LVDS\n"); RADEONRestoreLVDSRegisters(pScrn, info->ModeReg); break; case MT_DFP: if (radeon_output->TMDSType == TMDS_INT) { ErrorF("restore FP\n"); RADEONRestoreFPRegisters(pScrn, info->ModeReg); } else { ErrorF("restore FP2\n"); if (info->IsAtomBios) { unsigned char *RADEONMMIO = info->MMIO; uint32_t fp2_gen_cntl; atombios_external_tmds_setup(output, mode); /* r4xx atom has hard coded crtc mappings in the atom code * Fix it up here. */ fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK; if (radeon_crtc->crtc_id == 1) fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; else { if (radeon_output->Flags & RADEON_USE_RMX) fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; else fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; } OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); } else { RADEONRestoreDVOChip(pScrn, output); RADEONRestoreFP2Registers(pScrn, info->ModeReg); } } break; case MT_STV: case MT_CTV: ErrorF("restore tv\n"); RADEONRestoreDACRegisters(pScrn, info->ModeReg); RADEONRestoreTVRegisters(pScrn, info->ModeReg); break; default: ErrorF("restore dac\n"); RADEONRestoreDACRegisters(pScrn, info->ModeReg); } But I see ATIRadeonXXXX.kext adjust only CRTC registers. If so then we can't have good output on LVDS? Or software QE only? What about ATY_Caretta? Link to comment Share on other sites More sharing options...
dong Posted August 22, 2008 Share Posted August 22, 2008 I'm not looking into the control part of Carreta yet, just finished with the status part. Such that I can have a rough idea how the structure of DriverGlobal looks like. It will help when analyze the control codes. As you will see, it will also help us deal with status cmds. OSStatus STATUSDRVR(DriverGlobals *global, void* contents) { IONDRVControlParameters* pb = (IONDRVControlParameters*) contents; if ((global->flag4 & 1) == 0) return noErr; //display not power on? if (((global->flag4 >> 12 & 1) == 0) && (pb->code != cscGetPowerState)) return noErr; //display not wake up? if (pb->code > 227) return 0xFFEE; //227: cscGetDisplayParams switch (pb->code) { case 2: return DoGetMode(pb->params, global); case 3: return DoGetEntries(pb->params, global); case 4: return DoGetPages(pb->params, global); case 5: return DoGetBaseAddr(pb->params, global); case 7: return DoGetInterrupt(pb->params, global); case 8: return DoGetGamma(pb->params, global); case 9: return DoGetDefaultMode(pb->params, global); case 10: return DoGetCurrentMode(pb->params, global); case 11: return DoGetSync(pb->params, global); case 12: return DoGetConnection(pb->params, global); case 13: return DoGetModeTiming(pb->params, global); case 16: return DoGetConfiguration(pb->params, global); case 17: return DoGetNextResolution(pb->params, global); case 18: return DoGetVideoParameters(pb->params, global); case 22: return DoSupportsHardwareCursor(pb->params, global); case 23: return DoGetHardwareCursorState(pb->params, global); case 25: return DoGetPowerState(pb->params, global); case 27: return DoFetchDDCBlock(pb->params, global); case 29: return DoGetClutBehavior(pb->params, global); case 30: return DoGetTimingRanges(pb->params, global); case 31: return DoGetDetailTiming(pb->params, global); case 32: return DoATIGetCommunicationInfo(pb->params, global); case 34: return DoGetVideoStatus(pb->params, global); case 35: return DoGetScalerInfo(pb->params, global); case 36: return DoGetScaler(pb->params, global); case 37: return DoGetMirror(pb->params, global); case 38: return DoGetFeatureConfiguratoin(pb->params, global); //original source has the typo error case 39: return DoGetFeatureList(pb->params, global); case 128: return DoATIGetInfo(pb->params, global); case 226: return DoGetUnderscan(pb->params, global); case 227: return DoATIGetDispParams(pb->params, global); default: return 0xFFEE; } } OSStatus DoGetMode(void* para, DriverGlobal* global) { VDSwitchInfoRec* modeInfo = (VDSwitchInfoRec*) para; modeInfo->csPage = 0; modeInfo->csMode = global->currentDepth; modeInfo->csBaseAddr = global->baseAddr; return noErr; } OSStatus DoGetEntries(void* para, DriverGlobal* global) { VDSetEntryRecord* entryPtr = (VDSetEntryRecord*) para; if (entryPtr->ColorSpec == NULL) return 0xFFFFFFEE; ulong maxCount = 256; //pixelSize == 24/32 if (HALPixelSize(global, global->currentDepth, global->currentMode) == 16) maxCount = 32; if (entryPtr->csStart < -1) return 0xFFFFFFEE; if ((entryPtr->csStart >= 0) && ((entryPtr->csStart + entryPtr->csCount + 1) > maxCount)) return 0xFFFFFFEE; if ((entryPtr->csStart == -1) && ((entryPtr->csCount + 1) > maxCount)) return 0xFFFFFFEE; return HALGetDACIntoTable(global, entryPtr->csStart, entryPtr->csCount + 1, entryPtr->csTable); } OSStatus HALGetDACIntoTable(DriverGlobal* global, short start, short count, ColorSpec* table) { short start1; short start2 = -1; ulong size; if (global->colorDepth == 16) size = 8; //pixelSize == 16 else size = 1; HW_SetupPaletteAccess(global, global->connectorType); for (i = 0; i< count;i++) { if (start == -1) start1 = table[i].value; else start1 = start + i; if ((start1 == 0) || (start1 != (start2 + 1))) start2 = -1; HW_GetPaletteEntry(global, start1 * size, &table[i].rgb.red, &table[i].rgb.green, &table[i].rgb.blue, 16, (start2 == -1)); start2 = start1; } return noErr; } void HW_SetupPaletteAccess(DriverGlobal* global, Byte connectorType) { HW_SetPaletteAccess(global, connectorType); global->atisg->433 = connectorType; } void HW_SetPaletteAccess(DriverGlobal* global, Byte connectorType) { ulong lutControl = 0; ulong lutRWMode = 0; ulong blackOffset = 0; ulong whiteOffset = 0; ulong offset = 0; if (connectorType != 0) offset = 0x800; regw32(global, 0x6480, connectorType); //DC_LUT_RW_SELECT, 0:lowerHalf 1:upperHalf if (global->colorBits > 8) { //for pixelSize 32:10bitsEach or 64 lutRWMode = 1; lutControl = global->colorBits - 7; if (global->colorFormat != 1) { whiteOffset = 0x7FFF; lutControl--; lutControl |= 16; if (((global->colorFormat & 2) != 0) && (global->colorBits == 16)) whiteOffset = 0x7BFF; } if ((global->colorFormat & 2) != 0) lutControl |= 32; } regw32(global, 0x6484, lutRWMode); //DC_LUT_RW_MODE, 0:tableMode 1:linearMode regw32(global, 0x64C0 + offset, (lutControl | (lutControl << 8) | (lutControl << 16)); //DC_LUT_CONTROL, RGB each 8 bits regw32(global, 0x64CC + offset, blackOffset); //DC_LUT_BLACK_OFFSET for 3 color components regw32(global, 0x64C8 + offset, blackOffset); regw32(global, 0x64C4 + offset, blackOffset); regw32(global, 0x64D8 + offset, whiteOffset); //DC_LUT_WHITE_OFFSET for 3 color components regw32(global, 0x64D4 + offset, whiteOffset); regw32(global, 0x64D0 + offset, whiteOffset); } void HW_GetPaletteEntry(DriverGlobal* global, short offset, ushort* red, ushort* green, ushort* blue, Byte denoteBits, Boolean yesNo) { ulong colorRange = global->colorRange[offset]; ushort oldRange = (colorRange & 0x3FF00000) >> 20; //get red 10 bits *red = (ushort) NewRange(global, oldRange, 10, denoteBits); oldRange = (colorRange & 0xFFC00) >> 10; //get green 10 bits *green = (ushort) NewRange(global, oldRange, 10, denoteBits); oldRange = colorRange & 0x3FF; //get blue 10 bits *blue = (ushort) NewRange(global, oldRange, 10, denoteBits); } ulong NewRange(DriverGlobal* global, ushort oldRange, Byte colorBits, Byte denoteBits) { if (colorBits > denoteBits) return oldRange >> (colorBits - denoteBits); //use higher part else return (oldRange << (denoteBits - colorBits)) //use higher part to fill the gap | (oldRange >> (colorBits - denoteBits + colorBits)); } OSStatus DoGetPages(void* para, DriverGlobal* global) { (VDPageInfo*) para->csPage = 1; return noErr; } OSStatus DoGetBaseAddr(void* para, DriverGlobal* global) { VDPageInfo* baseAddrPtr = (VDPageInfo*) para; baseAddrPtr->csBaseAddr = 0; if (baseAddrPtr->csPage != 0) return 0xFFFFFFEE; baseAddrPtr->csBaseAddr = global->baseAddr; return noErr; } OSStatus DoGetInterrupt(void* para, DriverGlobal* global) { if ((global->flag4 >> 29 & 1) == 1) (ulong) *para = 0; else (ulong) *para = 1; return noErr; } OSStatus DoGetGamma(void* para, DriverGlobal* global) { (VDGammaRecord*) para->csGTable = 0; if (global->gammaRecord != NULL) (VDGammaRecord*) *para = global->gammaRecord; return noErr; } OSStatus DoGetDefaultMode(void* para, DriverGlobal* global) { (Byte) *para = global->currentModeID; return noErr; } OSStatus DoGetCurrentMode(void* para, DriverGlobal* global) { VDSwitchInfoRec* switchPtr = (VDSwitchInfoRec*) para; switchPtr->csMode = global->currentDepth; switchPtr->csData = global->currentModeID; switchPtr->csPage = 0; switchPtr->csBaseAddr = global->baseAddr; switchPtr->csReserved = 0; return noErr; } OSStatus DoGetSync(void* para, DriverGlobal* global) { if ((Byte)*para == 0) (Byte) *para = global->sync; else if ((Byte)*para == 255) (Byte) *para = 0x87; return noErr; } OSStatus DoGetConnection(void* para, DriverGlobal* global) { ushort ret = 0; do { if ((global->flag4 >> 7 & 1) == 1) { if (global->atisg->conInfo == NULL) kdelay(500); global->flag4 &= 0x7F; Byte var_9 = DoDetectNewConnection(global, 1); } ret = CheckConnectionInfo((VDDisplayConnectInfoRec*) para, global); if ((global->atisg->conInfo != NULL) && (global->atisg->conInfo != global->conInfo)) global->flag4 |= 0x80; } while ((global->flag4 >> 7 & 1) == 1); debug_connect_info((VDDisplayConnectInfoRec*) para); return ret; } Boolean DoDetectNewConnection(DriverGlobal* global, Byte val) { ulong edidP1 = 0; ulong edidP2 = 0; ConnectionInfo conInfo; if (DetectNewConnectionEnabled(global) == FALSE) return FALSE; GetEDIDProperties(global, global->connection, &edidP1); GetConnectionInfo(global, &conInfo, 0, 1, val); global->flag4 &= 0xFFFDFFFF; if ((global->connectedFlags == conInfo.connectedFlags) && (global->connectTaggedType == conInfo.connectTaggedType) && (global->112BF == conInfo.3) && (global->connectTaggedData == conInfo.connectTaggedData) && (global->112C1 == conInfo.5) && (global->edidP1 == conInfo.edidP1) && (global->edidP2 == conInfo.edidP2)) return CopyConectionInfo2Globals(global, &conInfo); CopyConectionInfo2Globals(global, &conInfo); ProgramCrsrState(global, 0, 0, 0, global->connectorType); InitScalerInfo(global); InitOutputs(global); InitDefault(global); GetEDIDProperties(global, global->connection, &edidP2); if (edidP1 != edidP2) { InitDisplayParameters(global, &global->dispPara2); memcpy(&global->dispPara1, &global->dispPara2, 0x260); } HALSetUpDetailTable(global); InitMemPartition(global); InitMonitorTables(global); if (global->modesNum == 0) { global->connectedFlags = 1; InitDefault(global); InitMemPartition(global); InitMonitorTables(global); } return TRUE; } Boolean DetectNewConnectionEnabled(DriverGlobal* global) { if ((global->flag4 >> 6 & 1) == 0) return FALSE; if ((global->flag4 & 0x40800) != 0) return FALSE; if (global->atisg->serviceID[global->connectorType] == NULL) return FALSE; return TRUE; } void ProgramCrsrState(DriverGlobal* global, ulong crsrX, ulong crsrY, ulong val3, Byte connectorType) { ulong hotSpotX = 0; ulong hotSpotY = 0; ulong offset = 0; if (val3 == 0) { crsrX = 0x1FFF; crsrY = 0x1FFF; } else { if (crsrX < 0) { hotSpotX = -crsrX; crsrX = 0; } if (crsrY < 0) { hotSpotY = -crsrY; crsrY = 0; } hotSpotX = (hotSpotX > 0x3F)?0x3F:hotSpotX; hotSpotY = (hotSpotY > 0x3F)?0x3F:hotSpotY; } ulong cursorAddress = global->cursorAddress + offset; ulong value2 = crsrX << 16 | crsrY; ulong value1 = hotSpotX << 16 | hotSpotY; if (connectorType == 0) { regw32(global, 0x6418, value1); //D1CUR_HOT_SPOT value1 = regr32(global, 0x6400); //D1CUR_CONTROL regw32(global, 0x6414, value2); //D1CUR_POSITION value2 = (global->cursorMode << 8) | (value1 & 0xFFFFFCFF) | 1; //set cursorMode and enable if (value2 != value1) regw32(global, 0x6400, value2); regw32(global, 0x6408, cursorAddress); //D1CUR_SURFACE_ADDRESS } else { regw32(global, 0x6C18, value1); //D2CUR_HOT_SPOT value1 = regr32(global, 0x6C00); //D2CUR_CONTROL if (global->atisg->62C != 0) global->atisg->cursorPosition = value2; regw32(global, 0x6C14, value2); //D2CUR_POSITION value2 = (global->cursorMode << 8) | (value1 & 0xFFFFFCFF) | 1; if (value2 != value1) regw32(global, 0x6C00, value2); regw32(global, 0x6C08, cursorAddress); //D2CUR_SURFACE_ADDRESS } WaitForCursorUpdate(global, connectorType); } void WaitForCursorUpdate(DriverGlobal* global, Byte connectorType) { Byte var_C = connectorType; } OSStatus CheckConnectionInfo(VDDisplayConnectInfoRec* displayInfo, DriverGlobal* global) { Byte DriversConnectorsLen = 1; ulong DriversConnectors[4] = {0x4, 0x18, 0, 0}; ushort ret = noErr; ulong flag = 0; displayInfo->csConnectFlags = 0; GetConnectionSense(global, global->connection, &var_10, &var_11); if (global->connection == 1) flag = 1 << kConnectionInactive; for (i = 0;i < DriversConnectorsLen;i++) { if ((global->connection & DriversConnectors[i + 1]) == 0) continue; //not DFP2&CRT1 if ((DriversConnectors[i] >> 1 & 1) == 0) break; flag |= 1 << kBuiltInConnection; break; } displayInfo->csDisplayType = global->monP->4; displayInfo->csConnectFlags |= 1 << kReportsHotPlugging; displayInfo->csConnectFlags |= 1 << kReportsHotPlugging; //a repeat if ((global->connection & global->edidFlags) != 0) //edid not available yet displayInfo->csConnectFlags |= 1 << kOverrideConnection;//needs do it manually else displayInfo->csConnectFlags |= 1 << kReportsTagging; displayInfo->csConnectFlags |= 1 << kReportsDDCConnection; ret = CheckLoadEDIDBlock(global, global->connection, 1, 0); if (ret == noErr) displayInfo->csConnectFlags |= 1 << kHasDDCConnection;//find a DDC display displayInfo->csConnectTaggedType = var_10; if (var_11 == 0xFF) { displayInfo->csConnectTaggedData = 0; displayInfo->csConnectFlags |= 1 << kTaggingInfoNonStandard; } else displayInfo->csConnectTaggedData = var_11; displayInfo->csConnectFlags |= flag; displayInfo->csDisplayComponent = 0; displayInfo->csConnectReserved = 0; return noErr; } void void GetConnectionSense(DriverGlobal* global, Byte connection, Byte* connectType, Byte* connectData) { if (connection == 8) //DFP2 Panel_GetSenseCode(global, connectType, connectData); else if (connection == 16) //CRT1 Apple_GetHWSenseCode(global, global->connectedFlags, connectType, connectData); else { *connectType = 7; *connectData = 0x3F; } } void Panel_GetSenseCode(DriverGlobal* global, Byte* connectType, Byte* connectData) { *connectType = 0x90; *connectData = 0xFF; } void debug_connect_info(VDDisplayConnectInfoRec* displayInfo) { const UChar aAllmodesvalid[28] = "AllModesValid "; const UChar aAllmodessafe[28] = "AllModesSafe "; const UChar aReportstagging[28] = "ReportsTagging "; const UChar aHasdirectconne[28] = "HasDirectConnection "; const UChar aIsmonodev[28] = "IsMonoDev "; const UChar aUncertainconne[28] = "UncertainConnection "; const UChar aTagginginfonon[28] = "TaggingInfoNonStandard "; const UChar aReportsddcconn[28] = "ReportsDDCConnection "; const UChar aHasddcconnecti[28] = "HasDDCConnection "; const UChar aConnectioninac[28] = "ConnectionInactive "; const UChar aDependentconne[28] = "DependentConnection "; const UChar aBuiltinconnect[28] = "BuiltInConnection "; const UChar aOverrideconnec[28] = "OverrideConnection "; const UChar aFastcheckfordd[28] = "FastCheckForDDC "; const UChar aReportshotplug[28] = "ReportsHotPlugging "; global const UChar aUnknownconnect[28] = "UnknownConnect "; global const UChar aPanelconnect[28] = "PanelConnect "; global const UChar aPaneltftconnec[28] = "PanelTFTConnect "; global const UChar aFixedmodecrtco[28] = "FixedModeCRTConnect "; global const UChar aMultimodecrt1c[28] = "MultiModeCRT1Connect "; global const UChar aMultimodecrt2c[28] = "MultiModeCRT2Connect "; global const UChar aMultimodecrt3c[28] = "MultiModeCRT3Connect "; global const UChar aMultimodecrt4c[28] = "MultiModeCRT4Connect "; global const UChar aModelessconnec[28] = "ModelessConnect "; global const UChar aFullpageconnec[28] = "FullPageConnect "; global const UChar aVgaconnect[28] = "VGAConnect "; global const UChar aNtscconnect[28] = "NTSCConnect "; global const UChar aPalconnect[28] = "PALConnect "; global const UChar aHrconnect[28] = "HRConnect "; global const UChar aPanelfstnconne[28] = "PanelFSTNConnect "; global const UChar aMonotwopagecon[28] = "MonoTwoPageConnect "; global const UChar aColortwopageco[28] = "ColorTwoPageConnect "; global const UChar aColor16connect[28] = "Color16Connect "; global const UChar aColor19connect[28] = "Color19Connect "; global const UChar aGenericcrt[28] = "GenericCRT "; global const UChar aGenericlcd[28] = "GenericLCD "; global const UChar aDdcconnect[28] = "DDCConnect "; global const UChar aNoconnect[28] = "NoConnect "; C_26_14195 = aUnknownconnect; memcpy(&var_A4, &C_26_14195, 0x5C); for (i = 0;i <= 14;i++); //dubug code obviously not compiled } OSStatus DoGetModeTiming(void* para, DriverGlobal* global) { VDTimingInfoRec* timingPtr = (VDTimingInfoRec*) para; ulong timingFlags = 0; timingPtr->csTimingFormat = kDeclROMtables; displayMode* mode = HALFindCrtcValues(global, timingPtr->csTimingMode); if (mode == NULL) return 0xFFFFFFCE; if (IsDetailMode(global, timingPtr->csTimingMode) || IsAliasMode(global, timingPtr->csTimingMode)) timingPtr->csTimingFormat = kDetailedTimingFormat; if ((mode->flag >> 3 & 1) == 1) timingFlags |= 0x40; //interlaced mode HALGetMonitorModeFlags(global, timingPtr->csTimingMode, &timingFlags); if ((mode->flag >> 6 & 1) == 1) timingFlags |= 8; //mode always be shown timingPtr->csTimingData = mode->timingMode; timingPtr->csTimingFlags = timingFlags; return noErr; } Boolean IsAliasMode(DriverGlobal* global, ulong modeID) { if (modeID >= 0) return FALSE; if (modeID > -5) return FALSE; return TRUE; } OSStatus DoGetConfiguration(void* para, DriverGlobal* global) { GetConfigurationRec* confPtr = (GetConfigurationRec*) para; //the structure need a definition Byte connection; DoNVPrefs(global, global->4E, FALSE, &connection); if (global->connectorType == 0) { confPtr->0 = global->50; confPtr->2 = global->4E; } else { confPtr->0 = global->58; confPtr->2 = global->56; } displayMode* mode = HALGetCrtcValues(global, confPtr->2, confPtr->0); if (mode == NULL) return 0xFFFFFFCE; confPtr->8 = 0; return noErr; } OSStatus DoGetNextResolution(void* para, DriverGlobal* global) { global diplayMode* myCrtcValues_14347; VDResolutionInfoRec* resolutionPtr = (VDResolutionInfoRec*) para; ulong modeID; displayMode* mode; Boolean find = FALSE; resolutionPtr->csDisplayModeID = 0; resolutionPtr->csHorizontalPixels = 0 resolutionPtr->csVerticalLines = 0; resolutionPtr->csRefreshRate = 0; resolutionPtr->csMaxDepthMode = 0; ulong previousID = resolutionPtr->csPreviousDisplayModeID; if (previousID == kDisplayModeIDFindFirstProgrammable) { mode = global->detailModes[0]; find = TRUE; } else if (previousID == kDisplayModeIDCurrent) { mode = HALGetCrtcValues(global, global->currentModeID, global->currentDepth); if (mode != NULL) find = TRUE; } else { if ((myCrtcValues_14347 != NULL) && (myCrtcValues_14347->modeID == previousID)) mode = myCrtcValues_14347; else { if (global->modesNum == 0) mode = NULL; else mode = global->modes[0]; if (IsDetailMode(global, previousID)) mode = global->detailModes[0]; } while(mode != NULL) { modeID = mode->modeID; if (previousID == kDisplayModeIDFindFirstResolution) { find = TRUE; break; } if (modeID == previousID) find = TRUE; else if (find) break; mode = HALGetNextCrtc(global, mode); } if (find) myCrtcValues_14347 = mode; else myCrtcValues_14347 = NULL; } if (!find) return 0xFFFFFFCE; if (mode == NULL) { resolutionPtr->csDisplayModeID = kDisplayModeIDNoMoreResolutions; return noErr; } resolutionPtr->csDisplayModeID = mode->modeID; resolutionPtr->csHorizontalPixels = mode->width; resolutionPtr->csVerticalLines = mode->height; resolutionPtr->csRefreshRate = HALGetRefreshRate(global, mode); resolutionPtr->csMaxDepthMode = kDepthMode6; if (((mode->flag & 0xF00 >> 8 & 1) == 1) && ((global->flag4 >> 26 & 1) == 1)) { //rotate resolutionPtr->csVerticalLines = mode->width; resolutionPtr->csHorizontalPixels = mode->height; } return noErr; } displayMode* HALGetCrtcValues(DriverGlobal* global, ulong modeID, ulong depthMode) { displayMode* mode = HALFindCrtcValues(global, modeID); if (mode == NULL) return NULL; DetailTimingState* DTState; if ((HALGetDetailTimingState(global, mode->modeID, DTState) == noErr) && (DTState->modeState == kDMSModeFree)) return NULL; //not used yet if (HALPixelSize(global, depthMode, mode) <= 7) return NULL; if (HALPixelSize(global, depthMode, mode) > HALMaxPixelSize(global, mode)) return NULL; return mode; } OSStatus DoGetVideoParameters(void* para, DriverGlobal* global) { VDVideoParametersInfoRec* videoParaPtr = (VDVideoParametersInfoRec*) para; ushort ret = noErr; ulong modeID = videoParaPtr->csDisplayModeID; if (modeID == 0) modeID = global->currentModeID; displayMode* mode = HALFindCrtcValues(global, modeID); if (mode == NULL) return 0xFFFFFFCE; videoParaPtr->csPageCount = 1; videoParaptr->csVPBlockPtr->vpBounds.top = 0; videoParaPtr->csVPBlockPtr->vpBounds.left = 0; videoParaPtr->csVPBlockPtr->vpHRes = 0x480055; videoParaPtr->csVPBlockPtr->vpVRes = 0x480044; videoParaPtr->csVPBlockPtr->VPVersion = 0; videoParaPtr->csVPBlockPtr->vpPackType = 0; videoParaPtr->csVPBlockPtr->vpPackSize = 0; videoParaPtr->csVPBlockPtr->vpPlaneBytes = 0; videoParaPtr->csVPBlockPtr->vpBaseOffset = 0; videoParaPtr->csVPBlockPtr->vpCmpSize = HALColorBits(global, videoParaPtr->csDepthMode, mode); videoParaPtr->csVPBlockPtr->vpPixelSize = HALPixelSize(global, videoParaPtr->csDepthMode, mode); ushort bitsPerPixel = videoParaPtr->csVPBlockPtr->vpPixelSize; if (bitsPerPixel < 0) bitsPerPixel += 7; ulong bytesPerPixel = bitsPerPixel / 8; if (videoParaPtr->csVPBlockPtr->vpPixelSize > 32) return 0xFFFFFFCE; if (videoParaPtr->csVPBlockPtr->vpPixelSize <= 7) return 0xFFFFFFCE; if (videoParaPtr->csVPBlockPtr->vpCmpSize > 8) return 0xFFFFFFCE; if (videoParaPtr->csVPBlockPtr->vpCmpSize <= 0) return 0xFFFFFFCE; if (bytesPerPixel == 0) return 0xFFFFFFCE; if (bytesPerPixel == 1) { videoParaPtr->csDeviceType = 0; //Direct videoParaPtr->csVPBlockPtr->vpPixelType = 0; videoParaPtr->csVPBlockPtr->vpCmpCount = 1; } else { videoParaPtr->csDeviceType = 2; //CLUT videoParaPtr->csVPBlockPtr->vpPixelType = 0x10; videoParaPtr->csVPBlockPtr->vpCmpCount = 3; } ulong height = mode->height; ulong width = mode->width; if (((mode->flag & 0xF00 >> 8 & 1) == 1) && (global->flag4 >> 26 & 1) == 1) { //rotate bit height = mode->width; width = mode->height; } videoParaPtr->vpBlockPtr->vpBounds.bottom = height; videoParaPtr->vpBlockPtr->vpBounds.right = width; videoParaPtr->vpBlockPtr->vpRowBytes = GetPitch(global, width, bytesPerPixel); if (((global->flag4 >> 13 & 1) == 1) //HWmirror && (global->currentModeID == modeID)) { //current mode videoParaPtr->vpBlockPtr->vpBounds.right = global->width; videoParaPtr->vpBlockPtr->vpBounds.bottom = global->height; videoParaPtr->vpBlockPtr->vpRowBytes = global->pitch; } else if (((mode->flag & 0xF00 >> 8 & 1) == 1) && ((global->flag4 >> 26 & 1) == 1)) { //rotate videoParaPtr->vpBlockPtr->vpBounds.right = global->height; videoParaPtr->vpBlockPtr->vpBounds.bottom = global->width; videoParaPtr->vpBlockPtr->vpRowBytes = GetPitch(global, global->height, bytesPerPixel); } if (videoParaPtr->vpBlockPtr->vpPixelSize > HALMaxPixelSize(global, mode)) ret = 0xFFCE; if ((ret == noErr) && (HALNeedSWScaler(global, mode, videoParaPtr->vpBlockPtr->vpPixelSize) == 1)) return 0xFFFFFFCE; return ret; } ulong HALColorBits(DriverGlobal* global, ushort depthMode, displayMode* mode) { const ulong colorBits[7] = {8, 5, 8, 10, 16, 16, 32}; if (depthMode < kDepthMode1) return 0; depthMode -= kDepthMode1; if (depthMode > 6) return 0; //only support a max of 6 depthMode return colorBits[depthMode]; } ulong HALPixelSize(DriverGlobal* global, ushort depthMode, displayMode* mode) { const ulong pixelSize[7] = {8, 16, 32, 32, 64, 64, 128}; if (depthMode < kDepthMode1) return 0; depthMode -= kDepthMode1; if (depthMode > 6) return 0; //only support a max of 6 depthMode return pixelSize[depthMode]; } OSStatus DoSupportsHardwareCursor(void* para, DriverGlobal* global) { (VDSupportsHardwareCursorRec*) para->csSupportsHardwareCursor = TRUE; return noErr; } OSStatus DoGetHardwareCursorState(void* para, DriverGlobal* global) { VDHardwareCursorDrawStateRec* hwCursorStatePtr = (VDHardwareCursorDrawStateRec*) para; hwCursorStatePtr->csCursorSet = global->cursorSet; //true if cursor was set if (global->cursorSet != FALSE) { hwCursorStatePtr->csCursorX = global->cursorX; hwCursorStatePtr->csCursorY = global->cursorY; hwCursorStatePtr->csCursorVisible = global->cursorVisible; //true if cursor visible } return noErr; } OSStatus DoGetPowerState(void* para, DriverGlobal* global) { VDPowerStateRec* powerStatePtr = (VDPowerStateRec*) para; if (global->powerState == kAVPowerOff) global->powerFlags = 1; //need refreshing when turn on it from off else global->powerFlags = 0; //otherwise no refresh need powerStatePtr->powerState = global->powerState; powerStatePtr->powerFlags = global->powerFlags | 0x28; //support power down sleep, wake to doze return noErr; } OSStatus DoFetchDDCBlock(void* para, DriverGlobal* global) { ushort ret = 0; VDDDCBlockRec* ddcBlockPtr = (VDDDCBlockRec*) para; if ((global->flag4 >> 11 & 1) == 1) return 0xFFFFFFED; if (ddcBlockPtr->ddcBlockNumber == 0) return 0xFFFFFFCE; if (ddcBlockPtr->ddcBlockType != 0) return 0xFFFFFFCE; if (ddcBlockPtr->ddcBlockNumber != 0) ddcBlockPtr->ddcFlags &= 0xFFFFFFFE; //clear bit0 if (ret != noErr) return ret; if ((ddcBlockPtr->ddcFlags & 1) == 1) CheckDDCConnection(global, global->connection, 1, &var_10, global->112CC, global->connectedFlags); ret = CheckLoadEDIDBlock(global, global->connection, ddcBlockPtr->ddcBlockNumber, ddcBlockPtr->ddcBlockData); return ret; } OSStatus DoGetClutBehavior(void* para, DriverGlobal* global) { if ((global->flag4 >> 8 & 1) == 1) (VDClutBehavior*) para = 0; else (VDClutBehavior*) para = 1; return noErr; } OSStatus DoGetTimingRanges(void* para, DriverGlobal* global) { return HALGetTimingRanges(global, (VDDisplayTimingRangeRec*) para, global->connection); } OSStatus HALGetTimingRanges(DriverGlobal* global, VDDisplayTimingRangeRec* timingRangePtr, Byte connection) { if (timingRangeRec->csRangeBlockIndex != 0) return 0xFFFFFFCE; //not first index return GetHWTimingRange(global, timingRangePtr, connection, 1); } OSStatus GetHWTimingRange(DriverGlobal* global, VDDisplayTimingRangeRec* timingRangePtr, Byte connection, Byte val) { const DisplayTimingRanges DTRs[0xF0] = { 0xF0, 0, ...... } if (timingRangePtr == NULL) return 0xFFFFFFEE; memcpy(timingRangePtr, DTRs, 0xF0); ulong Clock = global->atisg->sysClock; if (val == 0) Clock = Clock - Clock * 1000 / 10000 - 1; else if (((global->F0 >> 1 & 1) == 1) && (global->F4 != 0)) Clock = Clock - Clock * global->F4 / 10000; Clock = (Clock > 55000)?55000:Clock; timingRangePtr->csMinPixelClock = 708; timingRangePtr->csMaxPixelClock = (Clock > 110000)?110000:Clock; if ((connection >> 3 & 1) == 1) { //DFP2 if (timingRangePtr->csMinPixelClock < 708) timingRangePtr->csMinPixelClock = 708; if ((global->112B5 == 0) && (timingRangePtr->csMaxPixelClock > 33000)) timingRangePtr->csMaxPixelClock = 33000; else if (timingRangePtr->csMaxPixelClock > 16500) timingRangePtr->csMaxPixelClock = 16500; timingRangePtr->csReserved2 = timingRangePtr->csMinPixelClock; timingRangePtr->csReserved3 = (timingRangePtr->csMaxPixelClock > 16500)? 16500:timingRangePtr->csMaxPixelClock; timingRangePtr->csReserved1 = 1; if (global->112B5 == 0) { timingRangePtr->csReserved4 = timingRangePtr->csReserved2; timingRangePtr->csReserved5 = timingRangePtr->csReserved3; timingRangePtr->csReserved1 = 2; } } if ((connection >> 4 & 1) == 1) { //CRT1 if (timingRangePtr->csMinPixelClock < 708) timingRangePtr->csMinPixelClock = 708; if (timingRangePtr->csMaxPixelClock > 40000) timingRangePtr->csMaxPixelClock = 40000; } if (timingRangePtr->csMaxPixelClock > Clock) timingRangePtr->csMaxPixelClock = Clock; if (timingRangePtr->csReserved3 > Clock) timingRangePtr->csReserved3 = Clock; if (timingRangePtr->csReserved5 > Clock) timingRangePtr->csReserved5 = Clock; timingRangePtr->csMinPixelClock *= 10000; timingRangePtr->csMaxPixelClock *= 10000; timingRangePtr->csReserved2 *= 10000; timingRangePtr->csReserved3 *= 10000; timingRangePtr->csReserved4 *= 10000; timingRangePtr->csReserved5 *= 10000; timingRangePtr->csRangeBlockCount = 1; return noErr; } OSStatus DoGetDetailTiming(void* para, DriverGlobal* global) { return HALGetDetailTiming(global, (VDDetailedTimingRec*) para); } OSStatus HALGetDetailTiming(DriverGlobal* global, VDDetailedTimingRec* dtPtr) { ulong modeID = dtPtr->csDisplayModeID; if (HALArbitraryAvailable(global) == 0) return 0xFFFFFFEE; if (modeID == 0x3000) return 0xFFFFFFEE; BlockZero(dtPtr, dtPtr->csTimingSize); HALConvertAlias(global, &modeID); displayMode* mode = HALFindCrtcValues(global, modeID); if (mode == NULL) return 0xFFFFFFEE; mode = HALFindNativeTiming(global, mode, 1); if (mode == NULL) return 0xFFFFFFEE; Byte timingFlags = HALGetTimingFlagsRec(global, mode, global->activeFlags); if (HALGetDetailTimingState(global, modeID, DTState) != noErr) DTState = NULL; dtPtr->csDisplayModeID = mode->modeID; if (DTState != NULL) { dtPtr->csPixelClock = DTState->Clock; dtPtr->MinPixelClock = 0; dtPtr->csHorizontalActive = DTState->width; dtPtr->csVerticalActive = DTState->height; dtPtr->csDisplayModeState = DTState->modeState; dtPtr->csDisplayModeSeed = DTState->modeSeed; dtPtr->csDisplayModeAlias = DTState->modeAlias; } else { dtPtr->csPixelClock = mode->Clock * 10000; //Hz dtPtr->csMinPixelClock = 0; dtPtr->csHorizontalActive = mode->width; dtPtr->csVerticalActive = mode->height; dtPtr->csDisplayModeState = 1; dtPtr->csDisplayModeSeed = 0; dtPtr->csDisplayModeAlias = dtPtr->csDisplayModeID; } dtPtr->csMinPixelClock = dtPtr->csPixelClock; dtPtr->csMaxPixelClock = dtPtr->csPixelClock; if (mode->Clock != 0) var_2C = CalculateVCLK(global, mode->Clock, global->connectorType, timingFlags); else var_2C = 0; var_10 = var_2C; if (mode->Clock >= var_10) dtPtr->csMinPixelClock = var_10 * 10000; else dtPtr->csMaxPixelClock = var_10 * 10000; dtPtr->csHorizontalBlanking = mode->HTotal - dtPtr->csHorizontalActive; dtPtr->csHorizontalSyncOffset = mode->dHSyncS; dtPtr->csHorizontalSyncPulseWidth = mode->dHSyncE; dtPtr->csVerticalBlanking = mode->VTotal - dtPtr->csVerticalActive; dtPtr->csVerticalSyncOffset = dtPtr->dVSyncS; dtPtr->csVerticalSyncPulseWidth = dtPtr->dVSyncE; if ((mode->flag >> 3 & 1) == 1) dtPtr->csSignalConfig |= 4; if ((timingFlags >> 3 & 1) == 1) { dtPtr->csSignalConfig |= 1; dtPtr->csReserved1 = 1; if ((mode->flag >> 12 & 1) == 1) dtPtr->csReserved1 = 2; } if ((mode->flag & 1) == 1) dtPtr->csHorizontalSyncConfig = 1; if ((mode->flag >> 1 & 1) == 1) dtPtr->csVerticalSyncConfig = 1; dtPtr->csTimingSize = 0xA0; dtPtr->csSignalLevels = 0; return noErr; } OSStatus DoATIGetCommunicationInfo(void* para, DriverGlobal* global) { VDCommunicationInfoRec* commInfoPtr = (VDCommunicationInfoRec*) para; commInfoPtr->csBusID = 0; commInfoPtr->csBusType = 1; commInfoPtr->csMinBus = 0; commInfoPtr->csMaxBus = 0; commInfoPtr->csSupportedTypes = 7; commInfoPtr->csSupportedTypes = 15; commInfoPtr->csSupportedCommFlags = 2; return noErr; } OSStatus DoGetVideoStatus(void* para, DriverGlobal* global) { (Byte) para->0 = 0; return noErr; } OSStatus DoGetScalerInfo(void* para, DriverGlobal* global) { return HALGetScalerInfo(global, (VDScalerInfoRec*) para); } OSStatus HALGetScalerInfo(DriverGlobal* global, (VDScalerInfoRec*) scalerInfoPtr) { if (HALScalerAvailable(global) == 0) return 0xFFFFFFEE; scalerInfoPtr->csScalerFeatures = 0x1A; //more active clocks than pixels, enable scale an interlaced, enable scale a timing with insets if ((global->flag4 >> 26 & 1) == 1) scalerInfoPtr->csScalerFeatures |= 0x20; //enable rotate scalerInfoPtr->csScalerFeatures |= 4; //fewer active clocks than pixels global->14 = 0x1000; global->18 = 0x1000; scalerInfoPtr->csReserved1 = 0; scalerInfoPtr->csReserved2 = 0; scalerInfoPtr->csReserved3 = 0; return noErr; } OSStatus DoGetScaler(void* para, DriverGlobal* global) { return HALGetScaler(global, (VDScalerRec*) para); } OSStatus HALGetScaler(DriverGlobal* global, VDScalerRec* scalerPtr) { displayMode* mode; ulong modeID; DetailTimingState* DTState; ret = noErr; if (HALScalerAvailable(global) == FALSE) return 0xFFFFFFEE; modeID = scalerPtr->csDisplayModeID; HALConvertAlias(global, &modeID); mode = HALFindCrtcValues(global, modeID); if (mode == NULL) return 0xFFFFFFEE; scalerPtr->csScalerFlags = 0; if ((mode->flag >> 6 & 1) == 1) scalerPtr->csScalerFlags |= 1; //set bit0 scalerPtr->csHorizontalPixels = mode->width; scalerPtr->csVerticalPixels = mode->height; if (HALGetDetailTimingState(global, modeID, DTState) == 0) { scalerPtr->csDisplayModeSeed = DTState->modeSeed; scalerPtr->csDisplayModeState = DTState->modeState; scalerPtr->csHorizontalInset = DTState->horiInset; scalerPtr->csVerticalInset = DTState->verInset; scalerPtr->csScalerFlags |= mode->flag & 0xF00 >> 4; if ((scalerPtr->csScalerFlags >> 4 & 1) == 1) { //bit4: SwapAxesMask scalerPtr->csHorizontalPixels = mode->height; scalerPtr->csVerticalPixels = mode->width; } } else { scalerPtr->csDisplayModeSeed = 0; scalerPtr->csDisplayModeState = 1; scalerPtr->csHorizontalInset = 0; scalerPtr->csVerticalInset = 0; } return ret; } Boolean HALScalerAvailable(DriverGlobal* global) { if (HALArbitraryAvailable(global) == FALSE) return FALSE; InitScalerInfo(global); if (HW_ScalerAvailable(global, global->connectorType) == FALSE) return FALSE; return TRUE; } Boolean HALArbitraryAvailable(DriverGlobal* global) { return TRUE; } Boolean HW_ScalerAvailable(DriverGlobal* global, Byte connectorType) { Byte conType = connectorType; return TRUE; } OSStatus DoGetMirror(void* para, DriverGlobal* global) { RegEntryID* regID; ret = noErr; VDMirrorRec* mirrorPtr = (VDMirrorRec*) para; mirrorPtr->csMirrorFeatures = 1; //same depth only mirrorPtr->csMirrorSupportedFlags = 0x9F; //HW mirror, clipped or not, can center mirrorPtr->csMirrorFlags = global->11528 & 0xFFFFFFFC; //clear bit0,1 = not HW mirror yet if (HWMirrorCheck(global) == noErr) mirrorPtr->csMirrorFlags |= 1; //enable HW mirror if ((global->flag4 >> 13 & 1) == 1) mirrorPtr->csMirrorFlags |= 2; //is HW mirror now if (global->connectorType == 0) regID = global->atisg->mirrorEntryID[1]; else regID = global->atisg->mirrorEntryID[0]; if ((RegistryEntryIDCompare(mirrorPtr->csMirrorReuestID[0], NULL) == TRUE) || (RegistryEntryIDCompare(mirrorPtr->csMirrorReuestID[0], regID) == FALSE)) { if ((global->flag4 >> 13 & 1) == 1) //has HW mirror RegistryEntryIDCopy(regID, mirrorPtr->csMirrorResultID[0]); else RegistryEntryIDInit(mirrorPtr->csMirrorResultID[0]); } else RegistryEntryIDCopy(mirrorPtr->csMirrorReuestID[0], mirrorPtr->csMirrorResultID[0]); return ret; } OSStatus HWMirrorCheck(DriverGlobal* global) { if (global->driverNodesNum == 0) return 0xFFFFFFEF; if (global->atisg->mirrorEntryID[1] == NULL) return 0xFFFFFFEF; if (global->atisg->mirrorEntryID[0] == NULL) return 0xFFFFFFEF; if (global->atisg->43C != global->atisg->450) return 0xFFFFFFEF; if (global->atisg->434 <= 7) return 0xFFFFFFEF; if (global->atisg->448 <= 7) return 0xFFFFFFEF; if (global->atisg->438 <= 1) return 0xFFFFFFEF; if (global->atisg->44C <= 1) return 0xFFFFFFEF; return noErr; } OSStatus DoGetFeatureConfiguratoin(void* para, DriverGlobal* global) { ret = 0xFFEE; displayMode mode; DisplayParameters dispPara; ScaledParameters scaledPara; VDConfigurationRec* confPtr = (VDConfigurationRec*) para; confPtr->csConfigSupport = 0; confPtr->csConfigValue = 0; confPtr->csReserved1 = 0; confPtr->csReserved2 = 0; if (confPtr->csConfigFeature == "htid") { confPtr->csConfigSupport = 1; confPtr->csConfigValue = global->11550; confPtr->csReserved1 = 0; confPtr->csReserved2 = 1; return noErr; } if (confPtr->csConfigFeature == "rgi") { confPtr->csConfigSupport = 1; confPtr->csReserved1 = 0; confPtr->csReserved2 = 1; confPtr->csConfigValue = global->atisg->431; confPtr->csConfigValue |= 0x80000000; return noErr; } if (confPtr->csConfigFeature == "mrht") { confPtr->csConfigSupport = 1; ReadAsicTemperature(confPtr->csConfigValue, global); confPtr->csReserved1 = 0; confPtr->csReserved2 = 0x78; return noErr; } if (confPtr->csConfigFeature == "ncsp") { dispPara.size = 0x260; dispPara.2 = 0; ret = DoATIGetdispParams(&dispPara, global); if (ret != noErr) return ret; if ((global->currentMode == 0) || (global->112E8 == 0)) return 0xFFFFFFEE; displayMode mode = *(global->currentMode); mode.width = global->width; mode.height = global->height; CalculateScaledconfPtrms(global, &mode, global->scaledMode, &scaledconfPtr); confPtr->csConfigSupport = 1; var_C = global->height; if ((global->flag4 >> 30 & 1) == 1) var_C = global->11536; if ((global->flag4 >> 14 & 1) == 1) var_C = global->1152E; confPtr->csConfigValue = 100 - (var_C * 200 / global->112E8 + 1) / 2; if (global->powerState8D != 0) { var_C = global->width; if ((global->flag4 >> 30 & 1) == 1) var_C = global->11534; if ((global->flag4 >> 14 & 1) == 1) var_C = global->1152C; var_C = 100 - (var_C * 200 / global->112E0 + 1) / 2; if (confPtr->csConfigValue > var_C) confPtr->csConfigValue = var_C; } confPtr->csReserved1 = 0; confPtr->csReserved2 = 100; return noErr; } return ret; } OSStatus ReadAsicTemperature(ushort* value, DriverGlobal* global) { ulong var_24[6] = { //not used 7, 0x3F000000, 6, 0x3E800000, 5, 0x3E000000 }; Byte tempR = ReadLM63(global, 1); if ((tempR >> 7 & 1) == 1) temp= 0; //tempR < 0 else temp = tempR; (*value) = temp; return noErr; } OSStatus DoGetFeatureList(void* para, DriverGlobal* global) { UChar fsupported[5][4] = { "mrht", "htid", "rgi", "ncsp", "" }; if (para == NULL) return 0xFFFFFFCE; ulong size = (FeatureList*) para->size; if (size > 5) size = 5; UChar** feature = (FeatureList*) para->fsupported; if ((feature != NULL) && (size != 0)) for (i = 0;i < size;i++) feature[i] = fsupported[i]; (FeatureList*) para->size = 5; return noErr; } OSStatus DoATIGetInfo(void* para, DriverGlobal* global) { CreateInfo(global->atiInfo, global); ulong size = 0x4C; if ((ATIInfo*) para->size < size) (ATIInfo*) para->size = size; global->atiInfo->size = size; BlockCopy(global->atiInfo, (ATIInfo*) para, size); } void CreateInfo(ATIInfo* atiInfo, DriverGlobal* global) { atiInfo->4 = 1; atiInfo->8 = global->E4; atiInfo->10 = 0; atiInfo->IOMapBase = global->IOMapBase; atiInfo->20 = 0; atiInfo->2C = global->12C; atiInfo->30 = global->120; atiInfo->34 = global->130; atiInfo->38 = global->134; atiInfo->3C = global->130; atiInfo->40 = global->134; atiInfo->44 = 0x201; atiInfo->chipID = global->chipID; atiInfo->size = 0x4C; atiInfo->14 = 0; atiInfo->scanoutStart = global->scanoutStart; atiInfo->28 = global->CC; atiInfo->totalVram = global->totalVram; atiInfo->18 = global->E4; if ((global->flag4 >> 13 & 1) == 0) return; if (global->connectorType == 0) var_1C = global->atisg->totalVram; else var_1C = 0; atiInfo->C = var_1C; } OSStatus DoGetUnderscan(void* para, DriverGlobal* global) { (Byte) (*para) = global->underScan; return noErr; } OSStatus DoATIGetDispParams(void* para, DriverGlobal* global) { if ((DisplayParameters*) para->size != 0x260) return 0xFFFFFFCE; if ((DisplayParameters*) para->8 != 0) InitDisplayParameters(global, (DisplayParameters*) para); else memcpy((DisplayParameters*) para, global->dispPara2, 0x260); return noErr; } There are still mistakes in it, but the information it provides is useful. Link to comment Share on other sites More sharing options...
Slice Posted August 22, 2008 Author Share Posted August 22, 2008 I'm not looking into the control part of Carreta yet, just finished with the status part. Such that I can have a rough idea how the structure of DriverGlobal looks like. It will help when analyze the control codes.As you will see, it will also help us deal with status cmds. There are still mistakes in it, but the information it provides is useful. Yes!!! It will be very useful as we have no other sample for many status/command. At last I understand what you mean "DriverGlobal". It is not structure, there are no definition for it. It is common practice for compiler from high-level languages such as C++, Pascal etc. In these languages assumed that we have access to global variables from local procedure. So local variables allocated in stack and have access through stack pointer. For global variables there is frame pointer that always push into stack when some routine is called. So DriverGlobal is a place of all global variables. The pointer to it is always first argument of any functions. For example ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame ; IOATIR200Accelerator::IOATIR200Accelerator(OSMetaClass const*) // only one argument var_18 = dword ptr -18h //internal var var_14 = dword ptr -14h //internal var arg_0 = dword ptr 8 // Frame pointer arg_4 = dword ptr 0Ch // argument push ebp mov ebp, esp push ebx sub esp, 14h // spaces for internal vars in stack mov ebx, [ebp+arg_0] // Frame pointer obtained from outer caller mov eax, [ebp+arg_4] // argument of type OSMetaClass mov [esp+18h+var_14], eax // use it mov [esp+18h+var_18], ebx // send Frame pointer to internal routine call near ptr __ZN13IOAcceleratorC2EPK11OSMetaClass; IOAccelerator::IOAccelerator(OSMetaClass const*) mov dword ptr [ebx], offset __ZTV20IOATIR200Accelerator; `vtable for'IOATIR200Accelerator mov eax, ebx // return value add esp, 14h //free stack pop ebx pop ebp retn ; --------------------------------------------------------------------------- For this purpose Intel register EBP exists but the compiler ( or programmer ) is not so smart to use it. You made no mistake in its interpretation. Only you need no write global as argument of all functions. Continue! Link to comment Share on other sites More sharing options...
dong Posted August 22, 2008 Share Posted August 22, 2008 No, I still think DriverGlobal is really a structure used in purpose, just like ScrnInfoRec in linux source. In your example, the frame pointer you commented is actually a pointer pointing to the beginning of the class itself (just check any c++ document and you will see). It facilitates the access of other members and methods in the same class. So for each class method, there is such an extra argument, but not for any non-class procedure. There is actually a DriverGlobal* pointer member in Carreta class (located at offset of 0x204 from the beginning of the class) which I found out from the initialization procedures. Link to comment Share on other sites More sharing options...
TinuMe Posted August 31, 2008 Share Posted August 31, 2008 Just came across a OpenSolaris 2008.02 live DVD that supported the ATI Mobility X1400 right out of the box with Res, Toggle etc. Hope that might help. Thanks Link to comment Share on other sites More sharing options...
Slice Posted September 8, 2008 Author Share Posted September 8, 2008 I am here! Just came across a OpenSolaris 2008.02 live DVD that supported the ATI Mobility X1400 right out of the box with Res, Toggle etc.Hope that might help. Thanks Linux, Unix, Solaris - no problem, as well as Windows. The problem is MacOSX. Anyone! Any comment http://www.barbariangroup.com/posts/619-ch...d_line_on_a_mac Link to comment Share on other sites More sharing options...
dong Posted September 8, 2008 Share Posted September 8, 2008 newscreen is kind of thing like display preference but offer more resolution choices, that means it still depend on our framebuffer driver. CGError CGConfigureDisplayMode ( CGDisplayConfigRef configRef, CGDirectDisplayID display, CFDictionaryRef mode ); The display mode you provide must be one of the following: A dictionary returned by one of the CGDisplayBestMode functions, such as CGDisplayBestModeForParameters. A dictionary in the array returned by CGDisplayAvailableModes. I found this apple link: http://developer.apple.com/documentation/H...vers/index.html You may already know it, but I just see it and think it is useful. Link to comment Share on other sites More sharing options...
Slice Posted September 9, 2008 Author Share Posted September 9, 2008 newscreen is kind of thing like display preference but offer more resolution choices, that means it still depend on our framebuffer driver. OK! May be knowledge how a framebuffer driver is used will be helpful for its design. I found this apple link:http://developer.apple.com/documentation/H...vers/index.html You may already know it, but I just see it and think it is useful. Yes, it is useful to read. But I don't know how much relations between MacOS Classic and X. © 1999 Apple Computer, Inc. – (Last Updated 26 March 99) Nontheless I see some similarities. PCI display drivers have a category of kServiceCategoryNdrvDriver and a service type of kNdrvTypeIsVideo. They export a driver description structure and use the DoDriverIO entry point Link to comment Share on other sites More sharing options...
dong Posted September 9, 2008 Share Posted September 9, 2008 Yes, it is useful to read. But I don't know how much relations between MacOS Classic and X. ATI native drivers are definitely based on these outdated information. The discovery of the link is during the study of Carreta. If you read a little more, you will see it explains in detail what data structures (defined in IOMacOSVideo.h) are being used in most status and control cmds, these really help a lot during reverse engineering. Link to comment Share on other sites More sharing options...
Slice Posted September 10, 2008 Author Share Posted September 10, 2008 ATI native drivers are definitely based on these outdated information. The discovery of the link is during the study of Carreta. If you read a little more, you will see it explains in detail what data structures (defined in IOMacOSVideo.h) are being used in most status and control cmds, these really help a lot during reverse engineering. OK. I find very few command and very few possibilities in its. -- too old. These commands useful for carbon applications and we can take its into account. I found new drivers sources. From Apple!!! It is opensources IOKitUser.tar.gz. Inside I found interface for GA.plugin, EDID interpretation, modes list and change. kern_return_t IOCreatePlugInInterfaceForService(io_service_t service, CFUUIDRef pluginType, CFUUIDRef interfaceType, IOCFPlugInInterface *** theInterface, SInt32 * theScore) { ... static Boolean EDIDDescToDisplayTimingRangeRec( EDID * edid, EDIDGeneralDesc * desc, IODisplayTimingRange * range ) { UInt8 byte; ... static kern_return_t IOFBBuildModeList( IOFBConnectRef connectRef ) { ... __private_extern__ kern_return_t IOFBInstallMode( IOFBConnectRef connectRef, IODisplayModeID mode, IOFBDisplayModeDescription * desc, UInt32 driverFlags, IOOptionBits modeGenFlags ) { IOReturn ret = kIOReturnSuccess; ... These sources is concurrent so it much better then analogous Joblo or Linux sources. But they use abstract hardware calls (from BIOS, ROM, PEF or any else?). I am sick of conforming one sources to another. Link to comment Share on other sites More sharing options...
dong Posted September 10, 2008 Share Posted September 10, 2008 Well, these are possibly kernel client interface for IOGraphicsFamily. If you have a working IOGraphicsFamily, you may write useful applications to tweak the graphics setting by using these procedures. The "IOFBConnectRef" should be a reference to the framebufferClient instance. Yes, it still offer information on how the system communicates with IOGraphicsFamily. Link to comment Share on other sites More sharing options...
Slice Posted September 10, 2008 Author Share Posted September 10, 2008 Well, these are possibly kernel client interface for IOGraphicsFamily. If you have a working IOGraphicsFamily, you may write useful applications to tweak the graphics setting by using these procedures. The "IOFBConnectRef" should be a reference to the framebufferClient instance.Yes, it still offer information on how the system communicates with IOGraphicsFamily. It is useful! I agree that the interface is not a driver we try to write. I want to put your attention that it contain useful procedures and structures. I have 1. Joblo's procedures parse_edid and modes_db that adusted to Framebuffer use. But ATI fuctions in not good. 2. Linux's sources with good ATI function and other procedure interpret_edid. But these sources are not reliable for use inside Apple's Framebuffer. As I understand you have the same problem. 3. Now I see Apple's sources for interpret_EDID, create mode_set, and more for graphics driver. I think it is also information to study. Really I can take latest Joblo's project, correct it for me and say "that's all". I think it is not good practice. My purpose is to create best driver. Now I use my Ati.kext (uploaded in topic) without resolution switch (OK, I already have native resolution) and dream about QE. I wonder that no any tester confirm that my Ati.kext works or no for other Radeon. How can I do anything without help, support, testing, advices? Only Dong is here. AMD is a bad company. They give me no "developer support" even though I do registration. Link to comment Share on other sites More sharing options...
enzobelmont Posted September 11, 2008 Share Posted September 11, 2008 sorry Slice, i'm feeling useless. I've tried to contact ati but nothing happened.... I'm following very close your progress, but i've no skills to help you. Sorry. Link to comment Share on other sites More sharing options...
Slice Posted September 11, 2008 Author Share Posted September 11, 2008 sorry Slice, i'm feeling useless. I've tried to contact ati but nothing happened.... I'm following very close your progress, but i've no skills to help you. Sorry. You can help me if do testing of ATILead122+Ati.kext. Links at topic. You need to change ATILead.info.plist <key>@0,address</key> <integer>-805306368</integer> -- dunno your value, set 0 <key>@0,model</key> <string>ATY,RS300</string> -- your value RS400 <key>chipset-model</key> <string>ATY,RS300</string> Value for address can be find in your ioreg ioreg -l -x -w 1024 >ioreg.txt | | | +-o VGA@5 <class IOPCIDevice, registered, matched, active, busy 0, retain 11> | | | | { | | | | "IOPCIResourced" = Yes | | | | "IOInterruptControllers" = ("io-apic-0") | | | | "IOName" = "display" | | | | "subsystem-id" = <85300000> | | | | "IODeviceMemory" = (({"address"=0xffffffffc0000000,"length"=0x10000000}),{"parent"=({"address"=0x0,"length"=0x10000}),"offset"=0x9000,"length"=0x100},({"address"=0xffffffffb0100000,"length"=0x10000})) in the example 0xffffffffc0000000 or shortly 0xc0000000. Without Callisto! Link to comment Share on other sites More sharing options...
asstastic Posted September 11, 2008 Share Posted September 11, 2008 I wonder that no any tester confirm that my Ati.kext works or no for other Radeon. How can I do anything without help, support, testing, advices? Only Dong is here.AMD is a bad company. They give me no "developer support" even though I do registration. I'm sure more people would help with testing if they knew how but with the current state of the forum thread it gets very confusing for non-developers to keep track of what is going on, what files to test and how to test them. Link to comment Share on other sites More sharing options...
pere Posted September 11, 2008 Share Posted September 11, 2008 Hi to all... i follow this thread also from some time, and i will like to help/debug, i dont know programming, but i can dive into the code to change things (commenting lines, changing values, etc), i have xcode installed and willing, just need a little guide to know how to do the correct testing. My hardware: Ati X2300 (DEV: 718A) on sony vaio laptop (This graphic card is an old rebranded x1450) Link to comment Share on other sites More sharing options...
Slice Posted September 12, 2008 Author Share Posted September 12, 2008 Very rare skill is programmer! But I thought that not only noobs install MacOSX on PC! What do I need to explain? OK. How to test? 1. Install ATILead.kext and Ati.kext. 2. Correct its info.plist 3. Try to boot. 4. Catch messages to show me. 5. Undo all changes and rest. Details. 1. How to install kexts? Type in terminal. sudo -scp -r -v ~/Desktop/ATILead.kext /S*/L*/E*/ cp -r -v ~/Desktop/Ati.kext /S*/L*/E*/ rm -v /S*/L*/E*.ke* rm -v /S*/L*/E*.mke* diskutil repairpermissions / 2. How to correct info.plist? sudo -snano /S*/L*/E*/ATILead.kext/Contents/info.plist ctrl^o ctrl^x What to correct? See my previous post. 3. How to boot? Best in single user mode with -v -s keys. 4. How to catch messages? After boot with -s you may enter /sbin/fsck -fy/sbin/mount -uw / sh /etc/rc wait for all messagestype crtl^c dmesg >dmesgYourNick.txt exit exit If you can't boot make digital photo of screen If you successfully boot the type in terminal sudo -sdmesg >dmesgYourNick.txt ioreg -l -x -w 2048 >ioregYourNick.txt kextstat >kextstatYourNick.txt kextload -v RadeonPCI.kext ./RadeonDump -r 0,400 >regsYourNick.txt Check also xBench, OpenMark or other graphics tests. 5. How to finish tests? sudo -srm -r -v /S*/L*/E*/ATILead.kext rm -r -v /S*/L*/E*/Ati.kext reboot 6. How to rest? Take two bottle of beer... Is there any news here? For programmers/hackers/coders and so on. If you find an error at the boot try to understand what is wrong. Compatibility: at the moment for all except nVidia and Intel. Link to comment Share on other sites More sharing options...
Slice Posted September 12, 2008 Author Share Posted September 12, 2008 Thanks, i will try and post what i find. Got kernel panic.... im trying to get good pictures, but cant find where in the code the error comes from the kernel panic, if you like i can add iologs to see where the kernel panic comes, but first need to guess where the iologs should be added.... When KP you see hexadecimal values on screen. Find EIP register - it is address of last command Look for loading address of kext where KP is occur. It might be slightly less then address of KP. Then I can binary find a place in sources. Link to comment Share on other sites More sharing options...
Slice Posted September 12, 2008 Author Share Posted September 12, 2008 Thanks, doing it now....Panic (CPU 0 caller 0x001A8CD4) EIP: 0x34bfa33a If is not the correct loading adress, please tell me where to look for it. It looks like Ati.kext: (0x34bf123456) or ATILead or other with near address Link to comment Share on other sites More sharing options...
Slice Posted September 12, 2008 Author Share Posted September 12, 2008 Done: EIP: 0x34bfa33a Com.free.driver.ati (1.0.3)@ 0x34650000>0x34b5dfff Sorry, but this address is too far 0x34bfa33a - 0x34b5dfff = 0x9C33B = 639 803 ( Application Calculator in programmer's mode) But Ati.kext has size only 100kb. So this address is out of the kext. Try to look more carefully. It may be a problem of address as I said before. Link to comment Share on other sites More sharing options...
Slice Posted September 13, 2008 Author Share Posted September 13, 2008 I get this: | | | +-o EVGA@0 | | | | { | | | | "IOPCIResourced" = Yes | | | | "IOInterruptControllers" = ("io-apic-0","IOPCIMessagedInterruptController") | | | | "IOName" = "display" | | | | "subsystem-id" = | | | | "IODeviceMemory" = (({"address"=0xfffffffff0000000,"length"=0x4000000}),{"parent"=({"address"=0x0,"length"=0x10000}),"offset"=0x2000,"length"=0x100},({"address"=0xfffffffffc000000,"length"=0x10000})) | | | | "display-connect-flags" = | | | | "class-code" = | | | | "revision-id" = | | | | "assigned-addresses" = and insert it as 0x0000000.... Better i try to post a good picture.... No. "address"=0xfffffffff0000000 = 0xf0000000 Yes, show picture. Link to comment Share on other sites More sharing options...
pere Posted September 13, 2008 Share Posted September 13, 2008 Sorry cause my mistakes... i have clean my posts also, dont want to flood the thread. I added 0xf0000000 I have used plist editor for this, not text edit. , so it looked like: <key>@0,address</key> <integer>-268435456</integer <key>@0,model</key> <string>ATY,M64</string <key>chipset-model</key> <string>ATY,M64</string> Then got kernel panic on boot, i have attached two pics cause the camera didnt do a good job. Link to comment Share on other sites More sharing options...
Slice Posted September 13, 2008 Author Share Posted September 13, 2008 Sorry cause my mistakes... i have clean my posts also, dont want to flood the thread.I added 0xf0000000 I have used plist editor for this, not text edit. , so it looked like: @0,address -268435456 @0,model ATY,M64 chipset-model ATY,M64 Then got kernel panic on boot, i have attached two pics cause the camera didnt do a good job. Now all is clear. Bad reading name of card from ATOMBIOS. Actually ATOMBIOS doesn't contain card name. It is not hard to correct. For example using list of different names. EIP=0x3476733a Ati =0x34765000 relative address = 0x233a. It is in procedure GetConnectorInfoFromBIOS. KP is here. Some mistake in my codes. Actually Dong has good sources for GetConnectorInfo for ATOMBIOS. But very complex. Dong, look at my codes, please! Where is zero pointer for AtomBIOS? EDITED: Found! MasterDataStart is undefined! Sorry! int MasterDataStart; // rinfo->ROMHeaderStart = BIOS_IN16(0x48); if(rinfo->IsAtomBios) { // MasterDataStart = BIOS_IN16( rinfo->ROMHeaderStart + 32 ); tmp = BIOS_IN16( MasterDataStart + 22); // unassigned Should be // int MasterDataStart; // don't need local definition // rinfo->ROMHeaderStart = BIOS_IN16(0x48); if(rinfo->IsAtomBios) { // MasterDataStart = BIOS_IN16( rinfo->ROMHeaderStart + 32 ); tmp = BIOS_IN16(rinfo->MasterDataStart + 22); Link to comment Share on other sites More sharing options...
Recommended Posts