/** Performs mutltiple Search&Replace operations on the video bios memory. @param FindAndReplace Pointer to array of VBIOS_PATCH_BYTES. @param FindAndReplaceCount Number of VBIOS_PATCH_BYTES elements in a FindAndReplace array. @retval EFI_SUCCESS If no error occured. @retval other In case of error. **/ EFI_STATUS EFIAPI VideoBiosPatchBytes ( IN VBIOS_PATCH_BYTES *FindAndReplace, IN UINTN FindAndReplaceCount ) { EFI_STATUS Status; UINTN Index; UINTN NumReplaces; UINTN NumReplacesTotal; if (FindAndReplace == NULL || FindAndReplaceCount == 0) { return EFI_INVALID_PARAMETER; } DBG ("VideoBiosPatchBytes(%d patches):\n", FindAndReplaceCount); Status = VideoBiosUnlock (); if (EFI_ERROR (Status)) { DBG (" = not done.\n"); return Status; } NumReplaces = 0; NumReplacesTotal = 0; for (Index = 0; Index < FindAndReplaceCount; Index++) { NumReplaces = VideoBiosPatchSearchAndReplace ( (UINT8*)(UINTN)VBIOS_START, VBIOS_SIZE, FindAndReplace[Index].Find, FindAndReplace[Index].NumberOfBytes, FindAndReplace[Index].Replace, -1 ); NumReplacesTotal += NumReplaces; DBG (" patch %d: patched %d time(s)\n", Index, NumReplaces); } DBG (" patched %d time(s)\n", NumReplacesTotal); VideoBiosLock (); return EFI_SUCCESS; }
VOID set_mode ( vbios_map *map, UINT8 *edidInfo, edid_mode mode ) { UINTN NumReplaces; NV_MODELINE *mode_timing; UINTN Index; Index = 0; // patch first available mode DBG("PatchVBIOS: "); switch (map->bios) { case BT_INTEL: { DBG("BT_INTEL: "); NumReplaces = 0; NumReplaces = VideoBiosPatchSearchAndReplace ( (UINT8*)(UINTN)VBIOS_START, VBIOS_SIZE, (UINT8*)&DTD_1024[0], 18, edidInfo, -1 ); DBG (" patched %d time(s)\n", NumReplaces); return; } case BT_ATI_1: { ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table; DBG("BT_ATI_1\n"); DBG(" mode 0 (%dx%d) patched to %dx%d\n", mode_timing->usCRTC_H_Disp, mode_timing->usCRTC_V_Disp, mode.h_active, mode.v_active ); mode_timing->usCRTC_H_Total = mode.h_active + mode.h_blanking; mode_timing->usCRTC_H_Disp = mode.h_active; mode_timing->usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset; mode_timing->usCRTC_H_SyncWidth = mode.h_sync_width; mode_timing->usCRTC_V_Total = mode.v_active + mode.v_blanking; mode_timing->usCRTC_V_Disp = mode.v_active; mode_timing->usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset; mode_timing->usCRTC_V_SyncWidth = mode.v_sync_width; mode_timing->usPixelClock = mode.pixel_clock; break; } case BT_ATI_2: { ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table; DBG("BT_ATI_2\n"); DBG(" mode 0 (%dx%d) patched to %dx%d\n", mode_timing->usHActive, mode_timing->usVActive, mode.h_active, mode.v_active ); mode_timing->usHBlanking_Time = mode.h_blanking; mode_timing->usHActive = mode.h_active; mode_timing->usHSyncOffset = mode.h_sync_offset; mode_timing->usHSyncWidth = mode.h_sync_width; mode_timing->usVBlanking_Time = mode.v_blanking; mode_timing->usVActive = mode.v_active; mode_timing->usVSyncOffset = mode.v_sync_offset; mode_timing->usVSyncWidth = mode.v_sync_width; mode_timing->usPixClk = mode.pixel_clock; break; } case BT_NVDA: { DBG("BT_NVDA"); // totally revised on work by pene // http://www.projectosx.com/forum/index.php?showtopic=2562&view=findpost&p=22683 // Search for desired mode in our matrix for (Index = 0; Index < RESOLUTIONS_NUMBER; Index++) { if ((nvda_res[Index].HRes == mode.h_active) && (nvda_res[Index].VRes == mode.v_active)) { break; } } if (Index == RESOLUTIONS_NUMBER) { DBG(" - the patch is not ready for the desired resolution\n"); break; // not found } DBG (" - mode %dx%d\n", nvda_res[Index].HRes, nvda_res[Index].VRes); NumReplaces = VideoBiosPatchSearchAndReplace ( (UINT8*)(UINTN)VBIOS_START, VBIOS_SIZE, (UINT8*)&Sample0[0], 17, (UINT8*)&nvda_key0[Index].Matrix[0], -1 ); DBG (" patch 0: patched %d time(s)\n", NumReplaces); NumReplaces = VideoBiosPatchSearchAndReplace ( (UINT8*)(UINTN)VBIOS_START, VBIOS_SIZE, (UINT8*)&Sample1[0], 9, (UINT8*)&nvda_key1[Index].Matrix[0], -1 ); DBG (" patch 1: patched %d time(s)\n", NumReplaces); NumReplaces = VideoBiosPatchSearchAndReplace ( (UINT8*)(UINTN)VBIOS_START, VBIOS_SIZE, (UINT8*)&Sample2[0], 13, (UINT8*)&nvda_key2[Index].Matrix[0], -1 ); DBG (" patch 2: patched %d time(s)\n", NumReplaces); NumReplaces = VideoBiosPatchSearchAndReplace ( (UINT8*)(UINTN)VBIOS_START, VBIOS_SIZE, (UINT8*)&Sample3[0], 5, (UINT8*)&nvda_key3[Index].Matrix[0], -1 ); DBG (" patch 3: patched %d time(s)\n", NumReplaces); if ((*((UINT8*)(UINTN)(VBIOS_START + 0x34)) & 0x8F) == 0x80 ) { *((UINT8*)(UINTN)(VBIOS_START + 0x34)) |= 0x01; } mode_timing = (NV_MODELINE *) map->nv_mode_table; Index = 0; DBG ("NVDA mode_timing: %dx%d vbios mode %d patched!\n", mode.h_active, mode.v_active, Index); mode_timing[Index].usH_Total = mode.h_active + mode.h_blanking; mode_timing[Index].usH_Active = mode.h_active; mode_timing[Index].usH_SyncStart = mode.h_active + mode.h_sync_offset; mode_timing[Index].usH_SyncEnd = mode.h_active + mode.h_sync_offset + mode.h_sync_width; mode_timing[Index].usV_Total = mode.v_active + mode.v_blanking; mode_timing[Index].usV_Active = mode.v_active; mode_timing[Index].usV_SyncStart = mode.v_active + mode.v_sync_offset; mode_timing[Index].usV_SyncEnd = mode.v_active + mode.v_sync_offset + mode.v_sync_width; mode_timing[Index].usPixel_Clock = mode.pixel_clock/10000; break; } case BT_1: case BT_2: case BT_3: case BT_UNKNOWN: { DBG("unknown - not patching\n"); break; } } }