Index: branches/diebuche/i386/libsaio/915resolution.c =================================================================== --- branches/diebuche/i386/libsaio/915resolution.c (revision 131) +++ branches/diebuche/i386/libsaio/915resolution.c (revision 132) @@ -1,935 +0,0 @@ - -/* Copied from 915 resolution created by steve tomljenovic - * - * This code is based on the techniques used in : - * - * - 855patch. Many thanks to Christian Zietz (czietz gmx net) - * for demonstrating how to shadow the VBIOS into system RAM - * and then modify it. - * - * - 1280patch by Andrew Tipton (andrewtipton null li). - * - * - 855resolution by Alain Poirier - * - * This source code is into the public domain. - */ - -#include "libsaio.h" -#include "915resolution.h" -#include "../boot2/graphics.h" - -char * chipset_type_names[] = { - "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME", - "946GZ", "955X", "G965", "Q965", "965GM", "975X", - "P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500" -}; - -char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"}; - -int freqs[] = { 60, 75, 85 }; - - -UInt32 get_chipset_id(void) { - outl(0xcf8, 0x80000000); - return inl(0xcfc); -} - -chipset_type get_chipset(UInt32 id) { - chipset_type type; - - switch (id) { - case 0x35758086: - type = CT_830; - break; - - case 0x25608086: - type = CT_845G; - break; - - case 0x35808086: - type = CT_855GM; - break; - - case 0x25708086: - type = CT_865G; - break; - - case 0x25808086: - type = CT_915G; - break; - - case 0x25908086: - type = CT_915GM; - break; - - case 0x27708086: - type = CT_945G; - break; - - case 0x27748086: - type = CT_955X; - break; - - case 0x277c8086: - type = CT_975X; - break; - - case 0x27a08086: - type = CT_945GM; - break; - - case 0x27ac8086: - type = CT_945GME; - break; - - case 0x29708086: - type = CT_946GZ; - break; - - case 0x29a08086: - type = CT_G965; - break; - - case 0x29908086: - type = CT_Q965; - break; - - case 0x2a008086: - type = CT_965GM; - break; - - case 0x29e08086: - type = CT_X48; - break; - - case 0x2a408086: - type = CT_GM45; - break; - - case 0x2e108086: - case 0X2e908086: - type = CT_B43; - break; - - case 0x2e208086: - type = CT_P45; - break; - - case 0x2e308086: - type = CT_G41; - break; - - case 0x29c08086: - type = CT_G31; - break; - - case 0x29208086: - type = CT_G45; - break; - - case 0x81008086: - type = CT_500; - break; - - default: - type = CT_UNKWN; - break; - } - return type; -} - -vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) { - vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); - return ptr; -} - -vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) { - vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); - return ptr; -} - -vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) { - vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); - return ptr; -} - -char detect_bios_type(vbios_map * map, char modeline, int entry_size) { - UInt32 i; - UInt16 r1, r2; - - r1 = r2 = 32000; - - for (i=0; i < map->mode_table_size; i++) { - if (map->mode_table[i].resolution <= r1) { - r1 = map->mode_table[i].resolution; - } - else { - if (map->mode_table[i].resolution <= r2) { - r2 = map->mode_table[i].resolution; - } - } - - /* printf("r1 = %d r2 = %d\n", r1, r2); */ - } - - return (r2-r1-6) % entry_size == 0; -} - -char detect_ati_bios_type(vbios_map * map) { - return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0; -} - -void close_vbios(vbios_map * map); - -vbios_map * open_vbios(chipset_type forced_chipset) { - UInt32 z; - vbios_map * map = NEW(vbios_map); - for(z=0; zchipset_id = get_chipset_id(); - map->chipset = get_chipset(map->chipset_id); - } - else if (forced_chipset != CT_UNKWN) { - map->chipset = forced_chipset; - } - else { - map->chipset = CT_915GM; - } - - /* - * Map the video bios to memory - */ - - map->bios_ptr = (unsigned char *)VBIOS_START; - - /* - * check if we have ATI Radeon - */ - - map->ati_tables.base = map->bios_ptr; - map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER)); - if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") != 0) { - printf("Not an AtomBios Card\n"); - } else { - map->bios = BT_ATI_1; - } - - - /* - * check if we have NVidia - */ - if (map->bios != BT_ATI_1) { - int i = 0; - while (i < 512) { // we don't need to look through the whole bios, just the first 512 bytes - if ((map->bios_ptr[i] == 'N') - && (map->bios_ptr[i+1] == 'V') - && (map->bios_ptr[i+2] == 'I') - && (map->bios_ptr[i+3] == 'D')) - { - map->bios = BT_NVDA; - break; - } - i++; - } - } - - /* - * check if we have Intel - */ - - /*if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) { - printf( "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n"); - - printf("Chipset Id: %x\n", map->chipset_id); - - printf("Please report this problem to stomljen@yahoo.com\n"); - - close_vbios(map); - return 0; - }*/ - - /* - * check for others - */ - - if (map->chipset == CT_UNKWN) { - printf("Unknown chipset type and unrecognized bios.\n"); - - printf("915resolution only works with Intel 800/900 series graphic chipsets.\n"); - - printf("Chipset Id: %x\n", map->chipset_id); - close_vbios(map); - return 0; - } - - /* - * Figure out where the mode table is - */ - - if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA)) - { - unsigned char* p = map->bios_ptr + 16; - unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode)); - - while (p < limit && map->mode_table == 0) { - vbios_mode * mode_ptr = (vbios_mode *) p; - - if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) && - ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) { - - map->mode_table = mode_ptr; - } - - p++; - } - - if (map->mode_table == 0) { - printf("Unable to locate the mode table.\n"); - printf("Please run the program 'dump_bios' as root and\n"); - printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n"); - printf("Chipset: %s\n", chipset_type_names[map->chipset]); - close_vbios(map); - return 0; - } - } - else if (map->bios == BT_ATI_1) - { - map->ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + map->ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables; - unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)map->ati_tables.MasterDataTables)->StandardVESA_Timing; - ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset); - - map->ati_mode_table = (char *) &std_vesa->aModeTimings; - if (map->ati_mode_table == 0) { - printf("Unable to locate the mode table.\n"); - printf("Please run the program 'dump_bios' as root and\n"); - printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n"); - printf("Chipset: %s\n", chipset_type_names[map->chipset]); - close_vbios(map); - return 0; - } - map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER); - - if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2; - } - else if (map->bios == BT_NVDA) - { - unsigned short nv_data_table_offset = 0; - unsigned short nv_modeline_2_offset = 0; - unsigned short * nv_data_table; - NV_VESA_TABLE * std_vesa; - - int i = 0; - - while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only - if ((map->bios_ptr[i] == 0x44) - && (map->bios_ptr[i+1] == 0x01) - && (map->bios_ptr[i+2] == 0x04) - && (map->bios_ptr[i+3] == 0x00)) { - nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8)); - break; - } - i++; - } - - while (i < VBIOS_SIZE) { //We don't know how to locate it other way - if ((map->bios_ptr[i] == 0x00) && (map->bios_ptr[i+1] == 0x04) //this is the first 1024 modeline. - && (map->bios_ptr[i+2] == 0x00) && (map->bios_ptr[i+3] == 0x03) - && (map->bios_ptr[i+4] == 0x80) - && (map->bios_ptr[i+5] == 0x2F) - && (map->bios_ptr[i+6] == 0x10) - && (map->bios_ptr[i+7] == 0x10) - && (map->bios_ptr[i+8] == 0x05)) { - nv_modeline_2_offset = (unsigned short) i; - break; - } - i++; - } - - nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX)); - std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table); - - map->nv_mode_table = (char *) std_vesa->sModelines; - if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) { - map->nv_mode_table_2 = NULL; - } else { - map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset; - } - if (map->nv_mode_table == 0) { - printf("Unable to locate the mode table.\n"); - printf("Please run the program 'dump_bios' as root and\n"); - printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n"); - printf("Chipset: %s\n", chipset_type_names[map->chipset]); - close_vbios(map); - return 0; - } - map->mode_table_size = std_vesa->sHeader.usTable_Size; - } - - - /* - * Determine size of mode table - */ - - if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) { - vbios_mode * mode_ptr = map->mode_table; - - while (mode_ptr->mode != 0xff) { - map->mode_table_size++; - mode_ptr++; - } - } - - /* - * Figure out what type of bios we have - * order of detection is important - */ - if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) { - if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) { - map->bios = BT_3; - } - else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) { - map->bios = BT_2; - } - else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) { - map->bios = BT_1; - } - else { - printf("Unable to determine bios type.\n"); - printf("Please run the program 'dump_bios' as root and\n"); - printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n"); - - printf("Chipset: %s\n", chipset_type_names[map->chipset]); - printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr)); - - printf("Mode Table Entries: %u\n", map->mode_table_size); - return 0; - } - } - - return map; -} - -void close_vbios(vbios_map * map) { - FREE(map); -} - -void unlock_vbios(vbios_map * map) { - - map->unlocked = TRUE; - - switch (map->chipset) { - case CT_UNKWN: - break; - case CT_830: - case CT_855GM: - outl(0xcf8, 0x8000005a); - map->b1 = inb(0xcfe); - - outl(0xcf8, 0x8000005a); - outb(0xcfe, 0x33); - break; - case CT_845G: - case CT_865G: - case CT_915G: - case CT_915GM: - case CT_945G: - case CT_945GM: - case CT_945GME: - case CT_946GZ: - case CT_955X: - case CT_G965: - case CT_Q965: - case CT_965GM: - case CT_975X: - case CT_P35: - case CT_X48: - case CT_B43: - case CT_Q45: - case CT_P45: - case CT_GM45: - case CT_G41: - case CT_G31: - case CT_G45: - case CT_500: - - outl(0xcf8, 0x80000090); - map->b1 = inb(0xcfd); - map->b2 = inb(0xcfe); - outl(0xcf8, 0x80000090); - outb(0xcfd, 0x33); - outb(0xcfe, 0x33); - break; - } - - #if DEBUG - { - UInt32 t = inl(0xcfc); - printf("unlock PAM: (0x%08x)\n", t); - } -#endif -} - -void relock_vbios(vbios_map * map) { - - map->unlocked = FALSE; - - switch (map->chipset) { - case CT_UNKWN: - break; - case CT_830: - case CT_855GM: - outl(0xcf8, 0x8000005a); - outb(0xcfe, map->b1); - break; - case CT_845G: - case CT_865G: - case CT_915G: - case CT_915GM: - case CT_945G: - case CT_945GM: - case CT_945GME: - case CT_946GZ: - case CT_955X: - case CT_G965: - case CT_Q965: - case CT_965GM: - case CT_975X: - case CT_P35: - case CT_X48: - case CT_B43: - case CT_Q45: - case CT_P45: - case CT_GM45: - case CT_G41: - case CT_G31: - case CT_G45: - case CT_500: - - outl(0xcf8, 0x80000090); - outb(0xcfd, map->b1); - outb(0xcfe, map->b2); - break; - } - - #if DEBUG - { - UInt32 t = inl(0xcfc); - printf("relock PAM: (0x%08x)\n", t); - } - #endif -} - -void save_vbios(vbios_map * map) -{ - map->bios_backup_ptr = malloc(VBIOS_SIZE); - bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE); -} - -void restore_vbios(vbios_map * map) -{ - bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE); -} - - - -static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq, - unsigned long *clock, - UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank, - UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank) -{ - UInt32 hbl, vbl, vfreq; - - vbl = y + (y+1)/(20000/(11*freq) - 1) + 1; - - vfreq = vbl * freq; - hbl = 16 * (int)(x * (30 - 300000 / vfreq) / - + (70 + 300000 / vfreq) / 16 + 0); - - *vsyncstart = y; - *vsyncend = y + 3; - *vblank = vbl - 1; - *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1; - *hsyncend = x + hbl / 2 - 1; - *hblank = x + hbl - 1; - *clock = (x + hbl) * vfreq / 1000; -} - -void cvt_timings(UInt32 x, UInt32 y, UInt32 freq, - unsigned long *clock, - UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank, - UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced) -{ - UInt32 hbl, hbp, vbl, vsync, hperiod; - - if (!(y % 3) && ((y * 4 / 3) == x)) - vsync = 4; - else if (!(y % 9) && ((y * 16 / 9) == x)) - vsync = 5; - else if (!(y % 10) && ((y * 16 / 10) == x)) - vsync = 6; - else if (!(y % 4) && ((y * 5 / 4) == x)) - vsync = 7; - else if (!(y % 9) && ((y * 15 / 9) == x)) - vsync = 7; - else /* Custom */ - vsync = 10; - - if (!reduced) { - hperiod = (1000000/freq - 550) / (y + 3); - vbl = y + (550/hperiod) + 3; - hbp = 30 - ((300*hperiod)/1000); - hbl = (x * hbp) / (100 - hbp); - - *vsyncstart = y + 6; - *vsyncend = *vsyncstart + vsync; - *vblank = vbl - 1; - *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1; - *hsyncend = x + hbl / 2 - 1; - *hblank = x + hbl - 1; - - } else { - hperiod = (1000000/freq - 460) / y; - vbl = y + 460/hperiod + 1; - hbl = 160; - - *vsyncstart = y + 3; - *vsyncend = *vsyncstart + vsync; - *vblank = vbl - 1; - *hsyncstart = x + hbl / 2 - 32; - *hsyncend = x + hbl / 2 - 1; - *hblank = x + hbl - 1; - - } - *clock = (x + hbl) * 1000 / hperiod; -} - -void set_mode(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) { - UInt32 xprev, yprev; - UInt32 i = 0, j; // patch first available mode - -// for (i=0; i < map->mode_table_size; i++) { -// if (map->mode_table[0].mode == mode) { - switch(map->bios) { - case BT_1: - { - vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); - - if (bp) { - map->mode_table[i].bits_per_pixel = bp; - } - - res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0); - res->x1 = (x & 0xff); - - res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0); - res->y1 = (y & 0xff); - if (htotal) - res->x_total = ((htotal-x) & 0xff); - - if (vtotal) - res->y_total = ((vtotal-y) & 0xff); - } - break; - case BT_2: - { - vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); - - res->xchars = x / 8; - res->ychars = y / 16 - 1; - xprev = res->modelines[0].x1; - yprev = res->modelines[0].y1; - - for(j=0; j < 3; j++) { - vbios_modeline_type2 * modeline = &res->modelines[j]; - - if (modeline->x1 == xprev && modeline->y1 == yprev) { - modeline->x1 = modeline->x2 = x-1; - modeline->y1 = modeline->y2 = y-1; - - gtf_timings(x, y, freqs[j], &modeline->clock, - &modeline->hsyncstart, &modeline->hsyncend, - &modeline->hblank, &modeline->vsyncstart, - &modeline->vsyncend, &modeline->vblank); - - if (htotal) - modeline->htotal = htotal; - else - modeline->htotal = modeline->hblank; - - if (vtotal) - modeline->vtotal = vtotal; - else - modeline->vtotal = modeline->vblank; - } - } - } - break; - case BT_3: - { - vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); - - xprev = res->modelines[0].x1; - yprev = res->modelines[0].y1; - - for (j=0; j < 3; j++) { - vbios_modeline_type3 * modeline = &res->modelines[j]; - - if (modeline->x1 == xprev && modeline->y1 == yprev) { - modeline->x1 = modeline->x2 = x-1; - modeline->y1 = modeline->y2 = y-1; - - gtf_timings(x, y, freqs[j], &modeline->clock, - &modeline->hsyncstart, &modeline->hsyncend, - &modeline->hblank, &modeline->vsyncstart, - &modeline->vsyncend, &modeline->vblank); - if (htotal) - modeline->htotal = htotal; - else - modeline->htotal = modeline->hblank; - if (vtotal) - modeline->vtotal = vtotal; - else - modeline->vtotal = modeline->vblank; - - modeline->timing_h = y-1; - modeline->timing_v = x-1; - } - } - } - break; - case BT_ATI_1: - { - edid_mode mode; - VBEModeInfoBlock minfo; - unsigned short mode_n; - unsigned short vesaVersion; - - ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table; - - mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit | - maModeIsSupportedBit | - maGraphicsModeBit | - maLinearFrameBufferAvailBit, - 0, - &minfo, &vesaVersion ); - - if ( mode_n == modeEndOfList ) - { - minfo.XResolution = 1024; - minfo.YResolution = 768; - } - - - int m_status = getMode(&mode); - - if (m_status || (mode.h_active != x)) { - vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2)); - bzero(modeline, sizeof(vbios_modeline_type2)); - - cvt_timings(x, y, 60, &modeline->clock, - &modeline->hsyncstart, &modeline->hsyncend, - &modeline->hblank, &modeline->vsyncstart, - &modeline->vsyncend, &modeline->vblank, FALSE); - - mode.pixel_clock = modeline->clock /10; - mode.h_active = x; - mode.h_sync_offset = modeline->hsyncstart - x; - mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart; - mode.h_blanking = modeline->hblank - x; - mode.v_active = y; - mode.v_sync_offset = modeline->vsyncstart - y; - mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart; - mode.v_blanking = modeline->vblank - y; - - free(modeline); - m_status = 0; - } - - if (!m_status) { - while (i < (map->mode_table_size / sizeof(ATOM_MODE_TIMING))) - { - if (mode_timing[i].usCRTC_H_Disp == minfo.XResolution) { - mode_timing[i].usCRTC_H_Total = mode.h_active + mode.h_blanking; - mode_timing[i].usCRTC_H_Disp = mode.h_active; - mode_timing[i].usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset; - mode_timing[i].usCRTC_H_SyncWidth = mode.h_sync_width; - - mode_timing[i].usCRTC_V_Total = mode.v_active + mode.v_blanking; - mode_timing[i].usCRTC_V_Disp = mode.v_active; - mode_timing[i].usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset; - mode_timing[i].usCRTC_V_SyncWidth = mode.v_sync_width; - - mode_timing[i].usPixelClock = mode.pixel_clock; - } - i++; - } - } - } - break; - case BT_ATI_2: - { - edid_mode mode; - VBEModeInfoBlock minfo; - unsigned short mode_n; - unsigned short vesaVersion; - - ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table; - - mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit | - maModeIsSupportedBit | - maGraphicsModeBit | - maLinearFrameBufferAvailBit, - 0, - &minfo, &vesaVersion ); - - if ( mode_n == modeEndOfList ) - { - minfo.XResolution = 1024; - minfo.YResolution = 768; - } - - - int m_status = getMode(&mode); - - if (m_status || (mode.h_active != x)) { - vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2)); - bzero(modeline, sizeof(vbios_modeline_type2)); - - cvt_timings(x, y, 60, &modeline->clock, - &modeline->hsyncstart, &modeline->hsyncend, - &modeline->hblank, &modeline->vsyncstart, - &modeline->vsyncend, &modeline->vblank, FALSE); - - mode.pixel_clock = modeline->clock /10; - mode.h_active = x; - mode.h_sync_offset = modeline->hsyncstart - x; - mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart; - mode.h_blanking = modeline->hblank - x; - mode.v_active = y; - mode.v_sync_offset = modeline->vsyncstart - y; - mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart; - mode.v_blanking = modeline->vblank - y; - - free(modeline); - m_status = 0; - } - - if (!m_status) { - while (i < (map->mode_table_size / sizeof(ATOM_DTD_FORMAT))) - { - if (mode_timing[i].usHActive == minfo.XResolution) { - - mode_timing[i].usHBlanking_Time = mode.h_blanking; - mode_timing[i].usHActive = mode.h_active; - mode_timing[i].usHSyncOffset = mode.h_sync_offset; - mode_timing[i].usHSyncWidth = mode.h_sync_width; - - mode_timing[i].usVBlanking_Time = mode.v_blanking; - mode_timing[i].usVActive = mode.v_active; - mode_timing[i].usVSyncOffset = mode.v_sync_offset; - mode_timing[i].usVSyncWidth = mode.v_sync_width; - - mode_timing[i].usPixClk = mode.pixel_clock; - } - i++; - } - } - - } - break; - case BT_NVDA: - { - s_aspect aspect_ratio; - /* - * Get the aspect ratio for the requested mode - */ - if ((y * 16 / 9) == x) { - aspect_ratio.width = 16; - aspect_ratio.height = 9; - } else if ((y * 16 / 10) == x) { - aspect_ratio.width = 16; - aspect_ratio.height = 10; - } else if ((y * 5 / 4) == x) { - aspect_ratio.width = 5; - aspect_ratio.height = 4; - } else if ((y * 15 / 9) == x) { - aspect_ratio.width = 15; - aspect_ratio.height = 9; - } else { - aspect_ratio.width = 4; - aspect_ratio.height = 3; - } - - NV_MODELINE *mode_timing = (NV_MODELINE *) map->nv_mode_table; - NV_MODELINE_2 *mode_timing_2 = (NV_MODELINE_2 *) map->nv_mode_table_2; - - i = 0; - if (mode_timing_2[i].h_disp == 0x140) { //From 320x200 mode. - while (mode_timing_2[i].h_disp <= 0x800) { - - vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2)); - bzero(modeliner, sizeof(vbios_modeline_type2)); - - x = mode_timing_2[i].h_disp; - y = x * aspect_ratio.height / aspect_ratio.width; - - cvt_timings(x, y, 60, &modeliner->clock, - &modeliner->hsyncstart, &modeliner->hsyncend, - &modeliner->hblank, &modeliner->vsyncstart, - &modeliner->vsyncend, &modeliner->vblank, TRUE); - - mode_timing_2[i].h_disp = x; - mode_timing_2[i].v_disp = y; - mode_timing_2[i].h_blank = modeliner->hblank - x; - mode_timing_2[i].h_syncoffset = modeliner->hsyncstart - x; - mode_timing_2[i].h_syncwidth = modeliner->hsyncend - modeliner->hsyncstart; - mode_timing_2[i].v_blank = modeliner->vblank - y; - i++; - free(modeliner); - } - } - i = 0; - - while ((mode_timing[i].reserved3 & 0xff) == 0xff) { - x = mode_timing[i].usH_Active; - y = x * aspect_ratio.height / aspect_ratio.width; - - vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2)); - bzero(modeliner, sizeof(vbios_modeline_type2)); - - cvt_timings(x, y, 60, &modeliner->clock, - &modeliner->hsyncstart, &modeliner->hsyncend, - &modeliner->hblank, &modeliner->vsyncstart, - &modeliner->vsyncend, &modeliner->vblank, FALSE); - - mode_timing[i].usH_Total = x + modeliner->hblank; - mode_timing[i].usH_Active = x; - mode_timing[i].usH_Active_minus_One = x - 1; - mode_timing[i].usH_Active_minus_One_ = x - 1; - mode_timing[i].usH_SyncStart = modeliner->hsyncstart; - mode_timing[i].usH_SyncEnd = modeliner->hsyncend; - - mode_timing[i].usV_Total = y + modeliner->vblank; - mode_timing[i].usV_Active = y; - mode_timing[i].usV_Active_minus_One = y - 1; - mode_timing[i].usV_Active_minus_One_ = y - 1; - mode_timing[i].usV_SyncStart = modeliner->vsyncend; - mode_timing[i].usV_SyncEnd = modeliner->vsyncend; - - mode_timing[i].usPixel_Clock = modeliner->clock; - - i++; - } - } - - break; - case BT_UNKWN: - break; - } -// } -// } -} Index: branches/diebuche/i386/libsaio/915resolution.h =================================================================== --- branches/diebuche/i386/libsaio/915resolution.h (revision 131) +++ branches/diebuche/i386/libsaio/915resolution.h (revision 132) @@ -1,219 +0,0 @@ - -/* Copied from 915 resolution created by steve tomljenovic - * - * This code is based on the techniques used in : - * - * - 855patch. Many thanks to Christian Zietz (czietz gmx net) - * for demonstrating how to shadow the VBIOS into system RAM - * and then modify it. - * - * - 1280patch by Andrew Tipton (andrewtipton null li). - * - * - 855resolution by Alain Poirier - * - * This source code is into the public domain. - */ -#ifndef __915_RESOLUTION_H -#define __915_RESOLUTION_H - -#include "shortatombios.h" -#include "edid.h" - -#define NEW(a) ((a *)(malloc(sizeof(a)))) -#define FREE(a) (free(a)) - -#define VBIOS_START 0xc0000 -#define VBIOS_SIZE 0x10000 - -#define FALSE 0 -#define TRUE 1 - -#define MODE_TABLE_OFFSET_845G 617 - - -#define ATI_SIGNATURE1 "ATI MOBILITY RADEON" -#define ATI_SIGNATURE2 "ATI Technologies Inc" -#define NVIDIA_SIGNATURE "NVIDIA Corp" -#define INTEL_SIGNATURE "Intel Corp" - -typedef struct { - unsigned char width; - unsigned char height; -} s_aspect; - -/* - * NVidia Defines and structures - */ - -#define OFFSET_TO_VESA_TABLE_INDEX 2 - -typedef struct { - unsigned char ucTable_Major; - unsigned char ucTable_Minor; - unsigned char ucTable_Rev; - unsigned short usTable_Size; -} NV_COMMON_TABLE_HEADER; - -typedef struct { - unsigned short usPixel_Clock; - unsigned short usH_Active; - unsigned short usH_Active_minus_One; - unsigned short reserved1; - unsigned short usH_Active_minus_One_; - unsigned short usH_SyncStart; - unsigned short usH_SyncEnd; - unsigned short usH_Total; - unsigned short usV_Active; - unsigned short usV_Active_minus_One; - unsigned short reserved2; - unsigned short usV_Active_minus_One_; - unsigned short usV_SyncStart; - unsigned short usV_SyncEnd; - unsigned short usV_Total; - unsigned short reserved3; -} NV_MODELINE; - -typedef struct { - unsigned short h_disp; - unsigned short v_disp; - unsigned char h_blank; - unsigned char h_syncoffset; - unsigned char h_syncwidth; - unsigned char v_blank; - unsigned char v_syncwidth; -} NV_MODELINE_2; - -typedef struct { - NV_COMMON_TABLE_HEADER sHeader; - NV_MODELINE * sModelines; -} NV_VESA_TABLE; - -/*---*/ - - -typedef enum { - CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, - CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME, CT_946GZ, - CT_955X, CT_G965, CT_Q965, CT_965GM, CT_975X, - CT_P35, CT_X48, CT_B43, CT_Q45, CT_P45, - CT_GM45, CT_G41, CT_G31, CT_G45, CT_500 -} chipset_type; - - -typedef enum { - BT_UNKWN, BT_1, BT_2, BT_3, BT_ATI_1, BT_ATI_2, BT_NVDA -} bios_type; - -typedef struct { - unsigned char *base; - ATOM_ROM_HEADER *AtomRomHeader; - unsigned short *MasterCommandTables; - unsigned short *MasterDataTables; -} bios_tables_t; - -typedef struct { - UInt8 mode; - UInt8 bits_per_pixel; - UInt16 resolution; - UInt8 unknown; -} __attribute__((packed)) vbios_mode; - -typedef struct { - UInt8 unknow1[2]; - UInt8 x1; - UInt8 x_total; - UInt8 x2; - UInt8 y1; - UInt8 y_total; - UInt8 y2; -} __attribute__((packed)) vbios_resolution_type1; - -typedef struct { - unsigned long clock; - - UInt16 x1; - UInt16 htotal; - UInt16 x2; - UInt16 hblank; - UInt16 hsyncstart; - UInt16 hsyncend; - UInt16 y1; - UInt16 vtotal; - UInt16 y2; - UInt16 vblank; - UInt16 vsyncstart; - UInt16 vsyncend; -} __attribute__((packed)) vbios_modeline_type2; - -typedef struct { - UInt8 xchars; - UInt8 ychars; - UInt8 unknown[4]; - - vbios_modeline_type2 modelines[]; -} __attribute__((packed)) vbios_resolution_type2; - -typedef struct { - unsigned long clock; - - UInt16 x1; - UInt16 htotal; - UInt16 x2; - UInt16 hblank; - UInt16 hsyncstart; - UInt16 hsyncend; - - UInt16 y1; - UInt16 vtotal; - UInt16 y2; - UInt16 vblank; - UInt16 vsyncstart; - UInt16 vsyncend; - - UInt16 timing_h; - UInt16 timing_v; - - UInt8 unknown[6]; -} __attribute__((packed)) vbios_modeline_type3; - -typedef struct { - unsigned char unknown[6]; - - vbios_modeline_type3 modelines[]; -} __attribute__((packed)) vbios_resolution_type3; - -typedef struct { - UInt32 chipset_id; - chipset_type chipset; - bios_type bios; - - bios_tables_t ati_tables; - - UInt32 bios_fd; - unsigned char* bios_backup_ptr; - unsigned char* bios_ptr; - - vbios_mode * mode_table; - char * ati_mode_table; - char * nv_mode_table; - char * nv_mode_table_2; - - UInt32 mode_table_size; - UInt8 b1, b2; - - UInt8 unlocked; -} vbios_map; - - - -void display_map_info(vbios_map*); -vbios_map * open_vbios(chipset_type); -void close_vbios (vbios_map*); -void unlock_vbios(vbios_map*); -void relock_vbios(vbios_map*); -void save_vbios(vbios_map*); -void restore_vbios(vbios_map*); -void set_mode(vbios_map*, UInt32, UInt32, UInt32, UInt32, UInt32); -void list_modes(vbios_map *map, UInt32 raw); - -#endif Index: branches/diebuche/i386/libsaio/ati_resolution.c =================================================================== --- branches/diebuche/i386/libsaio/ati_resolution.c (revision 0) +++ branches/diebuche/i386/libsaio/ati_resolution.c (revision 132) @@ -0,0 +1,91 @@ +/* + * ati_resolution.c + * + * + * Created by Le Bidou on 19/03/10. + * Copyright 2010 ---. All rights reserved. + * + */ + +#include "ati_resolution.h" + +char detect_ati_bios_type(vbios_map * map) { + return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0; +} + +vbios_map * open_ati_vbios(vbios_map * map, bios_tables_t ati_tables) +{ + /* + * Locate the Standard VESA Table + */ + + ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables; + unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)ati_tables.MasterDataTables)->StandardVESA_Timing; + ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset); + + map->mode_table = (char *) &std_vesa->aModeTimings; + verbose("Standard VESA Table at offset * 0x%x\n", std_vesa_offset); + if (map->mode_table == 0) { + verbose("Unable to locate the mode table.\n"); + verbose("Please run the program 'dump_bios' as root and\n"); + verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n"); + + close_vbios(map); + return 0; + } + + //Determine Size of the Table + map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER); + + /* + * Find out type of table and how many entries it has + */ + + if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2; + if (map->bios == BT_ATI_2) { + map->modeline_num = map->mode_table_size / sizeof(ATOM_DTD_FORMAT); + verbose("Using DTD Format modelines\n"); + } else { + map->modeline_num = map->mode_table_size / sizeof(ATOM_MODE_TIMING); + verbose("Using Atom Mode Timing modelines\n"); + } + return map; +} + +bool ati_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y) +{ + ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->mode_table; + + if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usCRTC_H_Disp >= 640 )) { + + verbose("Mode %dx%d -> %dx%d\n",mode_timing[idx].usCRTC_H_Disp,mode_timing[idx].usCRTC_V_Disp, + *x, *y); + + mode_timing[idx].usCRTC_H_Disp = *x; + mode_timing[idx].usCRTC_V_Disp = *y; + } + + *x = mode_timing[idx + 1].usCRTC_H_Disp; + *y = mode_timing[idx + 1].usCRTC_V_Disp; + + return TRUE; +} + +bool ati_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y) +{ + ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->mode_table; + + if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usHActive >= 640 )) { + + verbose("Mode %dx%d -> %dx%d\n", mode_timing[idx].usHActive, mode_timing[idx].usHActive, + *x, *y); + + mode_timing[idx].usHActive = *x; + mode_timing[idx].usVActive = *y; + } + + *x = mode_timing[idx + 1].usHActive; + *y = mode_timing[idx + 1].usVActive; + + return TRUE; +} Index: branches/diebuche/i386/libsaio/ati_resolution.h =================================================================== --- branches/diebuche/i386/libsaio/ati_resolution.h (revision 0) +++ branches/diebuche/i386/libsaio/ati_resolution.h (revision 132) @@ -0,0 +1,34 @@ +/* + * ati_resolution.h + * + * + * Created by Le Bidou on 19/03/10. + * Copyright 2010 ---. All rights reserved. + * + */ + +#ifndef _ATI_RESOLUTION_H_ +#define _ATI_RESOLUTION_H_ + +#include "libsaio.h" +#include "autoresolution.h" +#include "shortatombios.h" + +#define ATI_SIGNATURE1 "ATI MOBILITY RADEON" +#define ATI_SIGNATURE2 "ATI Technologies Inc" + +typedef struct { + unsigned char *base; + ATOM_ROM_HEADER *AtomRomHeader; + unsigned short *MasterCommandTables; + unsigned short *MasterDataTables; +} bios_tables_t; + +char detect_ati_bios_type(vbios_map * map); + +vbios_map * open_ati_vbios(vbios_map * map, bios_tables_t ati_tables); + +bool ati_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y); +bool ati_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y); + +#endif \ No newline at end of file Index: branches/diebuche/i386/libsaio/vbe.c =================================================================== --- branches/diebuche/i386/libsaio/vbe.c (revision 131) +++ branches/diebuche/i386/libsaio/vbe.c (revision 132) @@ -29,6 +29,7 @@ #include "libsaio.h" #include "edid.h" #include "vbe.h" +#include "autoresolution.h" /* * Various inline routines for video I/O Index: branches/diebuche/i386/libsaio/vbe.h =================================================================== --- branches/diebuche/i386/libsaio/vbe.h (revision 131) +++ branches/diebuche/i386/libsaio/vbe.h (revision 132) @@ -176,7 +176,9 @@ maGraphicsModeBit = (1 << 4), /* 1 = graphics; 0 = text */ maModeIsNotVGACompatableBit = (1 << 5), /* 1 = not compat; 0 = compat */ maVGAMemoryModeNotAvailBit = (1 << 6), /* 1 = not avail; 0 = avail */ - maLinearFrameBufferAvailBit = (1 << 7) /* 1 = avail; 0 = not avail */ + maLinearFrameBufferAvailBit = (1 << 7), /* 1 = avail; 0 = not avail */ + maDoubleScanAvailBit = (1 << 8), /* 1 = avail; 0 = not avail */ + maInterlacedAvailBit = (1 << 9) /* 1 = avail; 0 = not avail */ }; /* Index: branches/diebuche/i386/libsaio/Makefile =================================================================== --- branches/diebuche/i386/libsaio/Makefile (revision 131) +++ branches/diebuche/i386/libsaio/Makefile (revision 132) @@ -42,8 +42,10 @@ cpu.o platform.o dsdt_patcher.o \ smbios_patcher.o fake_efi.o ext2fs.o \ hpet.o spd.o usb.o pci_setup.o \ - device_inject.o nvidia.o ati.o pci_root.o \ - convert.o mem.o 915resolution.o edid.o + device_inject.o nvidia.o ati.o \ + gma_resolution.o ati_resolution.o nvidia_resolution.o \ + pci_root.o convert.o mem.o \ + autoresolution.o edid.o SAIO_EXTERN_OBJS = console.o Index: branches/diebuche/i386/libsaio/autoresolution.c =================================================================== --- branches/diebuche/i386/libsaio/autoresolution.c (revision 0) +++ branches/diebuche/i386/libsaio/autoresolution.c (revision 132) @@ -0,0 +1,525 @@ + +/* Copied from 915 resolution created by steve tomljenovic + * + * This code is based on the techniques used in : + * + * - 855patch. Many thanks to Christian Zietz (czietz gmx net) + * for demonstrating how to shadow the VBIOS into system RAM + * and then modify it. + * + * - 1280patch by Andrew Tipton (andrewtipton null li). + * + * - 855resolution by Alain Poirier + * + * This source code is into the public domain. + */ + +#include "libsaio.h" +#include "autoresolution.h" +#include "nvidia_resolution.h" +#include "ati_resolution.h" +#include "gma_resolution.h" +#include "../boot2/graphics.h" + +char * chipset_type_names[] = { + "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME", + "946GZ", "955X", "G965", "Q965", "965GM", "975X", + "P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500" +}; + +UInt32 get_chipset_id(void) { + outl(0xcf8, 0x80000000); + return inl(0xcfc); +} + +chipset_type get_chipset(UInt32 id) { + chipset_type type; + + switch (id) { + case 0x35758086: + type = CT_830; + break; + + case 0x25608086: + type = CT_845G; + break; + + case 0x35808086: + type = CT_855GM; + break; + + case 0x25708086: + type = CT_865G; + break; + + case 0x25808086: + type = CT_915G; + break; + + case 0x25908086: + type = CT_915GM; + break; + + case 0x27708086: + type = CT_945G; + break; + + case 0x27748086: + type = CT_955X; + break; + + case 0x277c8086: + type = CT_975X; + break; + + case 0x27a08086: + type = CT_945GM; + break; + + case 0x27ac8086: + type = CT_945GME; + break; + + case 0x29708086: + type = CT_946GZ; + break; + + case 0x29a08086: + type = CT_G965; + break; + + case 0x29908086: + type = CT_Q965; + break; + + case 0x2a008086: + type = CT_965GM; + break; + + case 0x29e08086: + type = CT_X48; + break; + + case 0x2a408086: + type = CT_GM45; + break; + + case 0x2e108086: + case 0X2e908086: + type = CT_B43; + break; + + case 0x2e208086: + type = CT_P45; + break; + + case 0x2e308086: + type = CT_G41; + break; + + case 0x29c08086: + type = CT_G31; + break; + + case 0x29208086: + type = CT_G45; + break; + + case 0x81008086: + type = CT_500; + break; + + default: + type = CT_UNKWN; + break; + } + return type; +} + + +void gtf_timings(UInt32 x, UInt32 y, UInt32 freq, + unsigned long *clock, + UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank, + UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank) +{ + UInt32 hbl, vbl, vfreq; + + vbl = y + (y+1)/(20000/(11*freq) - 1) + 1; + + vfreq = vbl * freq; + hbl = 16 * (int)(x * (30 - 300000 / vfreq) / + + (70 + 300000 / vfreq) / 16 + 0); + + *vsyncstart = y; + *vsyncend = y + 3; + *vblank = vbl; + *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 ; + *hsyncend = x + hbl / 2; + *hblank = x + hbl; + *clock = (x + hbl) * vfreq / 1000; +} + + +void get_aspect_ratio(s_aspect* aspect, UInt32 x, UInt32 y) +{ + if ((y * 16 / 9) == x) { + aspect->width = 16; + aspect->height = 9; + } else if ((y * 16 / 10) == x) { + aspect->width = 16; + aspect->height = 10; + } else if ((y * 5 / 4) == x) { + aspect->width = 5; + aspect->height = 4; + } else if ((y * 15 / 9) == x) { + aspect->width = 15; + aspect->height = 9; + } else { + aspect->width = 4; + aspect->height = 3; + } + verbose("Aspect Ratio is %d/%d\n", aspect->width, aspect->height); +} + +void cvt_timings(UInt32 x, UInt32 y, UInt32 freq, + unsigned long *clock, + UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank, + UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced) +{ + UInt32 hbl, hbp, vbl, vsync, hperiod; + + if (!(y % 3) && ((y * 4 / 3) == x)) + vsync = 4; + else if (!(y % 9) && ((y * 16 / 9) == x)) + vsync = 5; + else if (!(y % 10) && ((y * 16 / 10) == x)) + vsync = 6; + else if (!(y % 4) && ((y * 5 / 4) == x)) + vsync = 7; + else if (!(y % 9) && ((y * 15 / 9) == x)) + vsync = 7; + else /* Custom */ + vsync = 10; + + if (!reduced) { + hperiod = (1000000/freq - 550) / (y + 3); + vbl = y + (550/hperiod) + 3; + hbp = 30 - ((300*hperiod)/1000); + hbl = (x * hbp) / (100 - hbp); + + *vsyncstart = y + 6; + *vsyncend = *vsyncstart + vsync; + *vblank = vbl - 1; + *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1; + *hsyncend = x + hbl / 2 - 1; + *hblank = x + hbl - 1; + + } else { + hperiod = (1000000/freq - 460) / y; + vbl = y + 460/hperiod + 1; + hbl = 160; + + *vsyncstart = y + 3; + *vsyncend = *vsyncstart + vsync; + *vblank = vbl - 1; + *hsyncstart = x + hbl / 2 - 32; + *hsyncend = x + hbl / 2 - 1; + *hblank = x + hbl - 1; + + } + *clock = (x + hbl) * 1000 / hperiod; +} + + + +void close_vbios(vbios_map * map); + +vbios_map * open_vbios(chipset_type forced_chipset) { + UInt32 z; + vbios_map * map = NEW(vbios_map); + for(z=0; zchipset_id = get_chipset_id(); + map->chipset = get_chipset(map->chipset_id); + verbose("Chipset is %s (pci id 0x%x)\n",chipset_type_names[map->chipset], map->chipset_id); + } + else if (forced_chipset != CT_UNKWN) { + map->chipset = forced_chipset; + } + else { + map->chipset = CT_915GM; + } + + /* + * Map the video bios to memory + */ + + map->bios_ptr=(unsigned char*)VBIOS_START; + + /* + * check if we have ATI Radeon and open atombios + */ + bios_tables_t ati_tables; + + ati_tables.base = map->bios_ptr; + ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER)); + if (strcmp ((char *) ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") == 0) { + map->bios = BT_ATI_1; + verbose("We have an AtomBios Card\n"); + return open_ati_vbios(map, ati_tables); + } + + + /* + * check if we have NVidia + */ + if (map->bios != BT_ATI_1) { + int i = 0; + while (i < 512) { // we don't need to look through the whole bios, just the firs 512 bytes + if ((map->bios_ptr[i] == 'N') + && (map->bios_ptr[i+1] == 'V') + && (map->bios_ptr[i+2] == 'I') + && (map->bios_ptr[i+3] == 'D')) + { + map->bios = BT_NVDA; + verbose("We have an NVIDIA Card\n"); + return open_nvidia_vbios(map); + break; + } + i++; + } + } + + /* + * check if we have Intel + */ + + if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA)) { + int i = 0; + while (i < VBIOS_SIZE) { // we don't need to look through the whole bios, just the firs 512 bytes + if ((map->bios_ptr[i] == 'I') + && (map->bios_ptr[i+1] == 'n') + && (map->bios_ptr[i+2] == 't') + && (map->bios_ptr[i+3] == 'e') + && (map->bios_ptr[i+4] == 'l')) + { + map->bios = BT_1; + verbose("We have an Intel Card\n"); + return open_intel_vbios(map); + break; + } + i++; + } + } + + /* + * Unidentified Chipset + */ + + if (map->chipset == CT_UNKWN) { + verbose("Unknown chipset type and unrecognized bios.\n"); + + verbose("autoresolution only works with Intel 800/900 series graphic chipsets.\n"); + + verbose("Chipset Id: %x\n", map->chipset_id); + close_vbios(map); + return 0; + } + + /* + * Should never get there + */ + return 0; +} + +void close_vbios(vbios_map * map) { + if (autoResolution == TRUE) autoResolution = FALSE; + FREE(map); +} + +void unlock_vbios(vbios_map * map) { + + map->unlocked = TRUE; + + switch (map->chipset) { + case CT_UNKWN: + break; + case CT_830: + case CT_855GM: + outl(0xcf8, 0x8000005a); + map->b1 = inb(0xcfe); + + outl(0xcf8, 0x8000005a); + outb(0xcfe, 0x33); + break; + case CT_845G: + case CT_865G: + case CT_915G: + case CT_915GM: + case CT_945G: + case CT_945GM: + case CT_945GME: + case CT_946GZ: + case CT_955X: + case CT_G965: + case CT_Q965: + case CT_965GM: + case CT_975X: + case CT_P35: + case CT_X48: + case CT_B43: + case CT_Q45: + case CT_P45: + case CT_GM45: + case CT_G41: + case CT_G31: + case CT_G45: + case CT_500: + + outl(0xcf8, 0x80000090); + map->b1 = inb(0xcfd); + map->b2 = inb(0xcfe); + outl(0xcf8, 0x80000090); + outb(0xcfd, 0x33); + outb(0xcfe, 0x33); + break; + } + + #if DEBUG + { + UInt32 t = inl(0xcfc); + printf("unlock PAM: (0x%08x)\n", t); + } +#endif +} + +void relock_vbios(vbios_map * map) { + + map->unlocked = FALSE; + + switch (map->chipset) { + case CT_UNKWN: + break; + case CT_830: + case CT_855GM: + outl(0xcf8, 0x8000005a); + outb(0xcfe, map->b1); + break; + case CT_845G: + case CT_865G: + case CT_915G: + case CT_915GM: + case CT_945G: + case CT_945GM: + case CT_945GME: + case CT_946GZ: + case CT_955X: + case CT_G965: + case CT_Q965: + case CT_965GM: + case CT_975X: + case CT_P35: + case CT_X48: + case CT_B43: + case CT_Q45: + case CT_P45: + case CT_GM45: + case CT_G41: + case CT_G31: + case CT_G45: + case CT_500: + + outl(0xcf8, 0x80000090); + outb(0xcfd, map->b1); + outb(0xcfe, map->b2); + break; + } + + #if DEBUG + { + UInt32 t = inl(0xcfc); + printf("relock PAM: (0x%08x)\n", t); + } + #endif +} + + +void save_vbios(vbios_map * map) +{ + map->bios_backup_ptr = malloc(VBIOS_SIZE); + bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE); +} + +void restore_vbios(vbios_map * map) +{ + bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE); +} + + +void patch_vbios(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) { + UInt32 i = 0; + bool err = TRUE; + /* + * Get the aspect ratio for the requested mode + */ + get_aspect_ratio(&map->aspect_ratio, x, y); + + i = x = y = 0; + + if (map->bios != BT_NVDA) { + while (i < map->modeline_num) { + if (x == 1400) x = 1440; + if (x == 1600) x = 1680; + + y = x * map->aspect_ratio.height / map->aspect_ratio.width; + switch (map->bios) { + case BT_1: + intel_set_mode_1(map, i, &x, &y); + break; + case BT_2: + intel_set_mode_2(map, i, &x, &y); + break; + case BT_3: + intel_set_mode_3(map, i, &x, &y); + break; + case BT_ATI_1: + ati_set_mode_1(map, i, &x, &y); + break; + case BT_ATI_2: + ati_set_mode_2(map, i, &x, &y); + break; + default: + break; + } + i++; + } + } + + if (map->bios == BT_NVDA) { + err = TRUE; + + x = y = 0; + while (err == TRUE) { + if (x == 1400) x = 1440; + if (x == 1600) x = 1680; + + y = x * map->aspect_ratio.height / map->aspect_ratio.width; + err = nvidia_set_mode(map, i, &x, &y, MAIN_VESA_TABLE); + + } + err = TRUE; + x = y = 0; + while (err == TRUE) { + if (x == 1400) x = 1440; + if (x == 1600) x = 1680; + + y = x * map->aspect_ratio.height / map->aspect_ratio.width; + err = nvidia_set_mode(map, i, &x, &y, SECOND_VESA_TABLE); + } + } +} \ No newline at end of file Index: branches/diebuche/i386/libsaio/autoresolution.h =================================================================== --- branches/diebuche/i386/libsaio/autoresolution.h (revision 0) +++ branches/diebuche/i386/libsaio/autoresolution.h (revision 132) @@ -0,0 +1,90 @@ + +/* Copied from 915 resolution created by steve tomljenovic + * + * This code is based on the techniques used in : + * + * - 855patch. Many thanks to Christian Zietz (czietz gmx net) + * for demonstrating how to shadow the VBIOS into system RAM + * and then modify it. + * + * - 1280patch by Andrew Tipton (andrewtipton null li). + * + * - 855resolution by Alain Poirier + * + * This source code is into the public domain. + */ +#ifndef __915_RESOLUTION_H +#define __915_RESOLUTION_H + +#include "edid.h" + +#define NEW(a) ((a *)(malloc(sizeof(a)))) +#define FREE(a) (free(a)) + +#define VBIOS_START 0xc0000 +#define VBIOS_SIZE 0x10000 + +#define FALSE 0 +#define TRUE 1 + +typedef struct { + unsigned char width; + unsigned char height; +} s_aspect; + + +typedef enum { + CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, + CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME, CT_946GZ, + CT_955X, CT_G965, CT_Q965, CT_965GM, CT_975X, + CT_P35, CT_X48, CT_B43, CT_Q45, CT_P45, + CT_GM45, CT_G41, CT_G31, CT_G45, CT_500 +} chipset_type; + + +typedef enum { + BT_UNKWN, BT_1, BT_2, BT_3, BT_ATI_1, BT_ATI_2, BT_NVDA +} bios_type; + + +typedef struct { + UInt32 chipset_id; + chipset_type chipset; + bios_type bios; + + UInt32 bios_fd; + unsigned char* bios_backup_ptr; + unsigned char* bios_ptr; + + char * mode_table; + char * nv_mode_table_2; + + UInt32 mode_table_size; + UInt32 modeline_num; + UInt8 b1, b2; + + s_aspect aspect_ratio; + + UInt8 unlocked; +} vbios_map; + +vbios_map * open_vbios(chipset_type); +void close_vbios (vbios_map*); +void unlock_vbios(vbios_map*); +void relock_vbios(vbios_map*); +void save_vbios(vbios_map*); +void restore_vbios(vbios_map*); + +void gtf_timings(UInt32 x, UInt32 y, UInt32 freq, + unsigned long *clock, + UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank, + UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank); + +/*void cvt_timings(UInt32 x, UInt32 y, UInt32 freq, + unsigned long *clock, + UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank, + UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, BOOL reduced);*/ + +void patch_vbios(vbios_map*, UInt32, UInt32, UInt32, UInt32, UInt32); + +#endif Index: branches/diebuche/i386/libsaio/nvidia_resolution.c =================================================================== --- branches/diebuche/i386/libsaio/nvidia_resolution.c (revision 0) +++ branches/diebuche/i386/libsaio/nvidia_resolution.c (revision 132) @@ -0,0 +1,119 @@ +/* + * nvidia_resolution.c + * + * + * Created by Le Bidou on 19/03/10. + * Copyright 2010 ---. All rights reserved. + * + */ + +#include "nvidia_resolution.h" + +vbios_map * open_nvidia_vbios(vbios_map *map) +{ + unsigned short nv_data_table_offset = 0; + unsigned short nv_modeline_2_offset = 0; + unsigned short * nv_data_table = NULL; + NV_VESA_TABLE * std_vesa; + + /* + * Locate the VESA Tables + */ + + int i = 0; + + while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only + if ((map->bios_ptr[i] == 0x44) + && (map->bios_ptr[i+1] == 0x01) + && (map->bios_ptr[i+2] == 0x04) + && (map->bios_ptr[i+3] == 0x00)) { + nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8)); + break; + } + i++; + } + //Second VESA Table on some nVidia 8xxx 9xxx and GT + while (i < VBIOS_SIZE) { //We don't know how to locate it other way + if ((map->bios_ptr[i] == 0x40) && (map->bios_ptr[i+1] == 0x01) //this is the first 320x200 modeline. + && (map->bios_ptr[i+2] == 0xC8) && (map->bios_ptr[i+3] == 0x00) + && (map->bios_ptr[i+4] == 0x28) + && (map->bios_ptr[i+5] == 0x18) + && (map->bios_ptr[i+6] == 0x08) + && (map->bios_ptr[i+7] == 0x08)) { + nv_modeline_2_offset = (unsigned short) i; + break; + } + i++; + } + + nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX)); + std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table); + map->mode_table = (char *) std_vesa->sModelines; + verbose("First Standard VESA Table at offset 0x%x\n", *nv_data_table); + + if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) { + map->nv_mode_table_2 = NULL; + verbose("There is no Second Standard VESA Table to patch\n"); + } else { + map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset; + verbose("Second Standard VESA Table at offset 0x%x\n", nv_modeline_2_offset); + } + + if (map->mode_table == NULL) { + verbose("Unable to locate the mode table.\n"); + verbose("Please run the program 'dump_bios' as root and\n"); + verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n"); + + close_vbios(map); + return 0; + } + + //This won't be used as there is no garanty this is right + map->mode_table_size = std_vesa->sHeader.usTable_Size; + + return map; +} + +bool nvidia_set_mode(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y, char Type) +{ + if (Type == MAIN_VESA_TABLE) { + NV_MODELINE * mode_timing = (NV_MODELINE *) map->mode_table; + + if ((mode_timing[idx].reserved3 & 0xff) != 0xff) return FALSE; + + if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usH_Active >= 640 )) { + + verbose("Mode %dx%d -> %dx%d ", mode_timing[idx].usH_Active, mode_timing[idx].usV_Active, + *x, *y); + + mode_timing[idx].usH_Active = *x; + mode_timing[idx].usH_Active_minus_One = *x - 1; + mode_timing[idx].usH_Active_minus_One_ = *x - 1; + mode_timing[idx].usV_Active = *y; + mode_timing[idx].usV_Active_minus_One = *y - 1; + mode_timing[idx].usV_Active_minus_One_ = *y - 1; + } + + *x = mode_timing[idx + 1].usH_Active; + *y = mode_timing[idx + 1].usV_Active; + } + + if (Type == SECOND_VESA_TABLE) { + NV_MODELINE_2 * mode_timing = (NV_MODELINE_2 *) map->nv_mode_table_2; + + if (mode_timing[idx].h_disp > 0x800) return FALSE; + + if ((*x != 0) && (*y != 0) && ( mode_timing[idx].h_disp >= 640 )) { + + verbose("Mode %dx%d -> %dx%d ", mode_timing[idx].h_disp, mode_timing[idx].v_disp, + *x, *y); + + mode_timing[idx].h_disp = *x; + mode_timing[idx].v_disp = *y; + } + + *x = mode_timing[idx + 1].h_disp; + *y = mode_timing[idx + 1].v_disp; + } + return TRUE; +} Index: branches/diebuche/i386/libsaio/nvidia_resolution.h =================================================================== --- branches/diebuche/i386/libsaio/nvidia_resolution.h (revision 0) +++ branches/diebuche/i386/libsaio/nvidia_resolution.h (revision 132) @@ -0,0 +1,74 @@ +/* + * nviviaresolution.h + * + * + * Created by Le Bidou on 19/03/10. + * Copyright 2010 ---. All rights reserved. + * + */ + +#ifndef _NVDA_RESOLUTION_HEADER_ +#define _NVDA_RESOLUTION_HEADER_ + +#include "libsaio.h" +#include "autoresolution.h" + +#define NVIDIA_SIGNATURE "NVIDIA Corp" + +#define OFFSET_TO_VESA_TABLE_INDEX 2 +#define MAIN_VESA_TABLE 0 +#define SECOND_VESA_TABLE 1 + +typedef struct { + unsigned char ucTable_Major; //These names are probably wrong + unsigned char ucTable_Minor; + unsigned char ucTable_Rev; + unsigned short usTable_Size; +} NV_COMMON_TABLE_HEADER; + +typedef struct { + unsigned short usPixel_Clock; + unsigned short usH_Active; + unsigned short usH_Active_minus_One; + unsigned short reserved1; + unsigned short usH_Active_minus_One_; + unsigned short usH_SyncStart; + unsigned short usH_SyncEnd; + unsigned short usH_Total; + unsigned short usV_Active; + unsigned short usV_Active_minus_One; + unsigned short reserved2; + unsigned short usV_Active_minus_One_; + unsigned short usV_SyncStart; + unsigned short usV_SyncEnd; + unsigned short usV_Total; + unsigned short reserved3; +} NV_MODELINE; + +typedef struct { + unsigned short h_disp; + unsigned short v_disp; + unsigned char h_blank; + unsigned char h_syncoffset; + unsigned char h_syncwidth; + unsigned char v_blank; + //unsigned char v_syncwidth; + unsigned char flags; //looks like flags & 1 means "Graphics Mode", to oppose to "Console Mode" + //on 7xxx the high four bits look like a mode id number. + //on 8xxx only the low four bits are used, standard graphics mode are always 5. + // it can be 1 (1400x1050 and 2048x1536) (HSync High, VSync High ?) + // 3 (1440x900, 1680x1050 and 1920x1200) (Hsync High, VSync Low ?) + // 3 (Standard Timings) (Hsync Low, VSync High ?) + // or 7 (1280x800 and 768x340) (Hync Low, VSync Low ?) +} NV_MODELINE_2; + +typedef struct { + NV_COMMON_TABLE_HEADER sHeader; + NV_MODELINE * sModelines; +} NV_VESA_TABLE; + +vbios_map * open_nvidia_vbios(vbios_map *map); + +bool nvidia_set_mode(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y, char Type); + +#endif \ No newline at end of file Index: branches/diebuche/i386/libsaio/edid.c =================================================================== --- branches/diebuche/i386/libsaio/edid.c (revision 131) +++ branches/diebuche/i386/libsaio/edid.c (revision 132) @@ -12,8 +12,8 @@ #include "edid.h" #include "vbe.h" #include "bootstruct.h" -//#include "graphics.h" + //static biosBuf_t bb; UInt32 xResolution = 0; @@ -50,30 +50,6 @@ } -int getMode(edid_mode *mode) -{ - unsigned char* edidInfo = readEDID(); - - if(!edidInfo) return 1; - - mode->pixel_clock = (edidInfo[55] << 8) | edidInfo[54]; - mode->h_active = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4); - mode->h_blanking = ((edidInfo[58] & 0x0F) << 8) | edidInfo[57]; - mode->v_active = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4); - mode->v_blanking = ((edidInfo[61] & 0x0F) << 8) | edidInfo[60]; - mode->h_sync_offset = ((edidInfo[65] & 0xC0) >> 2) | edidInfo[62]; - mode->h_sync_width = (edidInfo[65] & 0x30) | edidInfo[63]; - mode->v_sync_offset = (edidInfo[65] & 0x0C) | ((edidInfo[64] & 0x0C) >> 2); - mode->v_sync_width = ((edidInfo[65] & 0x3) << 2) | (edidInfo[64] & 0x03); - - - free( edidInfo ); - - if(!mode->h_active) return 1; - - return 0; - -} unsigned char* readEDID() { @@ -150,7 +126,10 @@ printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) ); return 0; } - } else return 0; + } else { + return 0; + } + blocks_left = 0; } while(blocks_left); Index: branches/diebuche/i386/libsaio/edid.h =================================================================== --- branches/diebuche/i386/libsaio/edid.h (revision 131) +++ branches/diebuche/i386/libsaio/edid.h (revision 132) @@ -34,6 +34,5 @@ unsigned char* readEDID(); void getResolution(UInt32* x, UInt32* y, UInt32* bp); -int getMode(edid_mode* mode); #endif \ No newline at end of file Index: branches/diebuche/i386/libsaio/gma_resolution.c =================================================================== --- branches/diebuche/i386/libsaio/gma_resolution.c (revision 0) +++ branches/diebuche/i386/libsaio/gma_resolution.c (revision 132) @@ -0,0 +1,236 @@ +/* + * gma_resolution.c + * + * + * Created by Le Bidou on 19/03/10. + * Copyright 2010 ---. All rights reserved. + * + */ + +#include "gma_resolution.h" + +char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"}; +int freqs[] = { 60, 75, 85 }; + + +vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) { + vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); + return ptr; +} + +vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) { + vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); + return ptr; +} + +vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) { + vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); + return ptr; +} + +char detect_bios_type(vbios_map * map, char modeline, int entry_size) { + UInt32 i; + UInt16 r1, r2; + + vbios_mode * mode_table = (vbios_mode *)map->mode_table; + + r1 = r2 = 32000; + + for (i=0; i < map->mode_table_size; i++) { + if (mode_table[i].resolution <= r1) { + r1 = mode_table[i].resolution; + } + else { + if (mode_table[i].resolution <= r2) { + r2 = mode_table[i].resolution; + } + } + + /*printf("r1 = %d r2 = %d\n", r1, r2);*/ + } + + return (r2-r1-6) % entry_size == 0; +} + +vbios_map * open_intel_vbios(vbios_map *map) +{ + /* + * Find the location of the Mode Table + */ + unsigned char* p = map->bios_ptr + 16; + unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode)); + + while (p < limit && map->mode_table == 0) { + vbios_mode* mode_ptr = (vbios_mode*) p; + + if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) && + ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) { + + map->mode_table = (char *)mode_ptr; + } + + p++; + } + + if (map->mode_table == 0) { + verbose("Unable to locate the mode table.\n"); + verbose("Please run the program 'dump_bios' as root and\n"); + verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n"); + + close_vbios(map); + return 0; + } + + /* + * Determine size of mode table + */ + + vbios_mode * mode_ptr = (vbios_mode *)map->mode_table; + + while (mode_ptr->mode != 0xff) { + map->mode_table_size++; + mode_ptr++; + } + + map->modeline_num = map->mode_table_size; + + /* + * Figure out what type of bios we have + * order of detection is important + */ + + if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) { + map->bios = BT_3; + } + else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) { + map->bios = BT_2; + } + else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) { + map->bios = BT_1; + } + else { + verbose("Unable to determine bios type.\n"); + verbose("Please run the program 'dump_bios' as root and\n"); + verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n"); + + return 0; + } + + return map; +} + + + +bool intel_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y) +{ + vbios_mode *mode_timing = (vbios_mode *) map->mode_table; + vbios_resolution_type1 * res = map_type1_resolution(map, mode_timing[idx].resolution); + + UInt32 actual_x = ((res->x2 & 0xf0) << 4) | (res->x1 & 0xff); + UInt32 actual_y = ((res->y2 & 0xf0) << 4) | (res->y1 & 0xff); + + if ((*x != 0) && (*y != 0) && ( actual_x >= 640 )) { + + printf("Mode %dx%d -> %dx%d ", actual_x, actual_y, *x, *y); + + res->x2 = (res->x2 & 0x0f) | ((*x >> 4) & 0xf0); + res->x1 = (*x & 0xff); + + res->y2 = ((*y >> 4) & 0xf0); + res->y1 = (*y & 0xff); + } + + res = map_type1_resolution(map, mode_timing[idx + 1].resolution); + + actual_x = ((res->x2 & 0xf0) << 4) | (res->x1 & 0xff); + actual_y = ((res->y2 & 0xf0) << 4) | (res->y1 & 0xff); + + *x = actual_x; + *y = actual_y; + + return TRUE; +} + +bool intel_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y) +{ + UInt32 xprev, yprev, j = 0; + + vbios_mode *mode_timing = (vbios_mode *) map->mode_table; + vbios_resolution_type2 * res = map_type2_resolution(map, mode_timing[idx].resolution); + + if ((*x != 0) && (*y != 0) && ((res->modelines[0].x1 + 1) >= 640 )) { + + printf("Mode %dx%d -> %dx%d ", res->modelines[0].x1 + 1, res->modelines[0].y1 + 1, *x, *y); + + res->xchars = *x / 8; + res->ychars = *y / 16 - 1; + xprev = res->modelines[0].x1; + yprev = res->modelines[0].y1; + + for(j = 0; j < 3; j++) { + vbios_modeline_type2 * mode = &res->modelines[j]; + + if (mode->x1 == xprev && mode->y1 == yprev) { + mode->x1 = mode->x2 = *x-1; + mode->y1 = mode->y2 = *y-1; + + gtf_timings(*x, *y, freqs[j], &mode->clock, + &mode->hsyncstart, &mode->hsyncend, + &mode->hblank, &mode->vsyncstart, + &mode->vsyncend, &mode->vblank); + + mode->htotal = mode->hblank; + mode->vtotal = mode->vblank; + } + } + } + + res = map_type2_resolution(map, mode_timing[idx + 1].resolution); + + *x = res->modelines[0].x1 + 1; + *y = res->modelines[0].y1 + 1; + + return TRUE; +} + +bool intel_set_mode_3(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y) +{ + UInt32 xprev, yprev, j = 0; + + vbios_mode *mode_timing = (vbios_mode *) map->mode_table; + vbios_resolution_type3 * res = map_type3_resolution(map, mode_timing[idx].resolution); + + if ((*x != 0) && (*y != 0) && ((res->modelines[0].x1 + 1) >= 640 )) { + + printf("Mode %dx%d -> %dx%d ", res->modelines[0].x1 + 1, res->modelines[0].y1 + 1, *x, *y); + + xprev = res->modelines[0].x1; + yprev = res->modelines[0].y1; + + for(j = 0; j < 3; j++) { + vbios_modeline_type3 * mode = &res->modelines[j]; + + if (mode->x1 == xprev && mode->y1 == yprev) { + mode->x1 = mode->x2 = *x-1; + mode->y1 = mode->y2 = *y-1; + + gtf_timings(*x, *y, freqs[j], &mode->clock, + &mode->hsyncstart, &mode->hsyncend, + &mode->hblank, &mode->vsyncstart, + &mode->vsyncend, &mode->vblank); + + mode->htotal = mode->hblank; + mode->vtotal = mode->vblank; + + mode->timing_h = *y-1; + mode->timing_v = *x-1; + } + } + } + res = map_type3_resolution(map, mode_timing[idx + 1].resolution); + + *x = res->modelines[0].x1 + 1; + *y = res->modelines[0].y1 + 1; + + return TRUE; +} \ No newline at end of file Index: branches/diebuche/i386/libsaio/gma_resolution.h =================================================================== --- branches/diebuche/i386/libsaio/gma_resolution.h (revision 0) +++ branches/diebuche/i386/libsaio/gma_resolution.h (revision 132) @@ -0,0 +1,103 @@ +/* + * gma_resolution.h + * + * + * Created by Le Bidou on 19/03/10. + * Copyright 2010 ---. All rights reserved. + * + */ + +#ifndef _GMA_RESOLUTION_H_ +#define _GMA_RESOLTUION_H_ + +#include "libsaio.h" +#include "autoresolution.h" + +#define MODE_TABLE_OFFSET_845G 617 +#define INTEL_SIGNATURE "Intel Corp" + +typedef struct { + UInt8 mode; + UInt8 bits_per_pixel; + UInt16 resolution; + UInt8 unknown; +} __attribute__((packed)) vbios_mode; + +typedef struct { + UInt8 unknow1[2]; + UInt8 x1; + UInt8 x_total; + UInt8 x2; + UInt8 y1; + UInt8 y_total; + UInt8 y2; +} __attribute__((packed)) vbios_resolution_type1; + +typedef struct { + unsigned long clock; + + UInt16 x1; + UInt16 htotal; + UInt16 x2; + UInt16 hblank; + UInt16 hsyncstart; + UInt16 hsyncend; + UInt16 y1; + UInt16 vtotal; + UInt16 y2; + UInt16 vblank; + UInt16 vsyncstart; + UInt16 vsyncend; +} __attribute__((packed)) vbios_modeline_type2; + +typedef struct { + UInt8 xchars; + UInt8 ychars; + UInt8 unknown[4]; + + vbios_modeline_type2 modelines[]; +} __attribute__((packed)) vbios_resolution_type2; + +typedef struct { + unsigned long clock; + + UInt16 x1; + UInt16 htotal; + UInt16 x2; + UInt16 hblank; + UInt16 hsyncstart; + UInt16 hsyncend; + + UInt16 y1; + UInt16 vtotal; + UInt16 y2; + UInt16 vblank; + UInt16 vsyncstart; + UInt16 vsyncend; + + UInt16 timing_h; + UInt16 timing_v; + + UInt8 unknown[6]; +} __attribute__((packed)) vbios_modeline_type3; + +typedef struct { + unsigned char unknown[6]; + + vbios_modeline_type3 modelines[]; +} __attribute__((packed)) vbios_resolution_type3; + + +vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res); +vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res); +vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res); + +char detect_bios_type(vbios_map * map, char modeline, int entry_size); + +vbios_map * open_intel_vbios(vbios_map *); + +bool intel_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y); +bool intel_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y); +bool intel_set_mode_3(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y); + +#endif \ No newline at end of file Index: branches/diebuche/i386/boot2/graphics.c =================================================================== --- branches/diebuche/i386/boot2/graphics.c (revision 131) +++ branches/diebuche/i386/boot2/graphics.c (revision 132) @@ -387,6 +387,8 @@ break; } + if (refreshRate != 60) refreshRate = 60; + // // FIXME : generateCRTCTiming() causes crash. // @@ -429,9 +431,7 @@ err = setVBEMode( mode | kLinearFrameBufferBit, NULL ); if ( err != errSuccess ) - { break; - } // Set 8-bit color palette. @@ -461,7 +461,10 @@ bootArgs->Video.v_depth = minfo.BitsPerPixel; bootArgs->Video.v_rowBytes = minfo.BytesPerScanline; bootArgs->Video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr); - +#if DEBUG + gui.screen.mm = minfo.MemoryModel; + gui.screen.attr = minfo.ModeAttributes; +#endif } while ( 0 ); Index: branches/diebuche/i386/boot2/boot.c =================================================================== --- branches/diebuche/i386/boot2/boot.c (revision 131) +++ branches/diebuche/i386/boot2/boot.c (revision 132) @@ -59,7 +59,7 @@ #include "gui.h" #include "platform.h" #include "edid.h" -#include "915resolution.h" +#include "autoresolution.h" long gBootMode; /* defaults to 0 == kBootModeNormal */ bool gOverrideKernel; @@ -131,15 +131,11 @@ //========================================================================== // execKernel - Load the kernel image (mach-o) and jump to its entry point. -static int ExecKernel(void *binary, vbios_map *map) +static int ExecKernel(void *binary) { entry_t kernelEntry; int ret; - UInt32 params[4]; - int count; - params[3] = 0; - bootArgs->kaddr = bootArgs->ksize = 0; ret = DecodeKernel(binary, @@ -167,40 +163,11 @@ sleep(kBootErrorTimeout); } - //if the vbios patch have been applied restore it before performing fake efi stuff - if (autoResolution == TRUE) { - unlock_vbios(map); - restore_vbios(map); - relock_vbios(map); - } - + setupFakeEfi(); - //Reapply the vbios patch before setting mode for boot graphics - if (autoResolution == TRUE) { - count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4); - if ( count < 3 ) { - getResolution(¶ms[0], ¶ms[1], ¶ms[2]); - } - else - { - if ( params[2] == 256 ) params[2] = 8; - if ( params[2] == 555 ) params[2] = 16; - if ( params[2] == 888 ) params[2] = 32; - } - - if (params[0]!=0 && params[1]!=0) { - - unlock_vbios(map); - - set_mode(map, params[0], params[1], params[2], 0, 0); - - relock_vbios(map); - } - } + verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64"); - verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64"); - // Cleanup the PXE base code. if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) { @@ -226,14 +193,6 @@ else drawBootGraphics(); - //Boot Graphis are set finalize and free vbios patch structures - if (autoResolution == TRUE) { - unlock_vbios(map); - restore_vbios(map); - relock_vbios(map); - close_vbios(map); - } - finalizeBootStruct(); // Jump to kernel's entry point. There's no going back now. @@ -371,37 +330,43 @@ UInt32 params[4]; int count; params[3] = 0; - vbios_map * map = open_vbios(CT_UNKWN); + autoResolution = TRUE; // Override AutoResolution default getBoolForKey(kAutoResolutionKey, &autoResolution, &bootInfo->bootConfig); + vbios_map * map = open_vbios(CT_UNKWN); + //Saving the bios in case we have to unpatch it + save_vbios(map); + if (autoResolution == TRUE) { + //Get Resolution from Graphics Mode key count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4); - if ( count < 3 ) + if ( count < 3 ){ + //If no Graphics Mode key, get from EDID getResolution(¶ms[0], ¶ms[1], ¶ms[2]); - else - { + verbose("EDID Resolution: %dx%d\n",params[0], params[1]); + } + } else { if ( params[2] == 256 ) params[2] = 8; if ( params[2] == 555 ) params[2] = 16; if ( params[2] == 888 ) params[2] = 32; - } + } - if (params[0]!=0 && params[1]!=0) { - vbios_map * map = open_vbios(CT_UNKWN); - - unlock_vbios(map); - - save_vbios(map); - - set_mode(map, params[0], params[1], params[2], 0, 0); - - relock_vbios(map); - - verbose("Patched resolution mode to %dx%d.\n", params[0], params[1]); - } - } + if (params[0]!=0 && params[1]!=0) { + + unlock_vbios(map); + + patch_vbios(map, params[0], params[1], params[2], 0, 0); + + relock_vbios(map); + #if DEBUG + printf("Press Any Key...\n"); + getc(); + #endif + } + if (useGUI) { /* XXX AsereBLN handle error */ @@ -474,6 +439,50 @@ updateVRAM(); } + /* + * AutoResolution - Reapply the patch or cancel if Graphics Mode was incorrect + * or EDID Info was insane + */ + getBoolForKey(kAutoResolutionKey, &autoResolution, &bootInfo->bootConfig); + + //Restore the vbios for Cancelation + if ((autoResolution == FALSE) && map) { + + unlock_vbios(map); + + restore_vbios(map); + + relock_vbios(map); + + close_vbios(map); + + } + if ((autoResolution == TRUE) && map) { + //Reapply patch in case resolution have changed + + count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4); + if ( count < 3 ) { + getResolution(¶ms[0], ¶ms[1], ¶ms[2]); + } + else + { + if ( params[2] == 256 ) params[2] = 8; + if ( params[2] == 555 ) params[2] = 16; + if ( params[2] == 888 ) params[2] = 32; + } + + if (params[0]!=0 && params[1]!=0) { + + unlock_vbios(map); + + patch_vbios(map, params[0], params[1], params[2], 0, 0); + + relock_vbios(map); + + close_vbios(map); + } + } + // Find out which version mac os we're booting. if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion)) { if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) { @@ -656,7 +665,7 @@ } } else { /* Won't return if successful. */ - ret = ExecKernel(binary, map); + ret = ExecKernel(binary); } } Index: branches/diebuche/i386/boot2/gui.c =================================================================== --- branches/diebuche/i386/boot2/gui.c (revision 131) +++ branches/diebuche/i386/boot2/gui.c (revision 132) @@ -12,6 +12,7 @@ #include "appleboot.h" #include "vers.h" #include "edid.h" +#include "autoresolution.h" #define THEME_NAME_DEFAULT "Default" static const char *theme_name = THEME_NAME_DEFAULT; @@ -557,7 +558,7 @@ int initGUI(void) { - int val; + int val, count; #ifdef EMBED_THEME config_file_t *config; @@ -568,7 +569,8 @@ #else int len; char dirspec[256]; - + + // find theme name in boot.plist getValueForKey( "Theme", &theme_name, &len, &bootInfo->bootConfig ); if ((strlen(theme_name) + 27) > sizeof(dirspec)) { return 1; @@ -578,18 +580,15 @@ return 1; } #endif - // parse display size parameters - if (autoResolution == TRUE) { - VBEModeInfoBlock minfo; - unsigned short mode_n; - unsigned short vesaVersion; - - mode_n = getVESAModeWithProperties( screen_params[0], screen_params[1], 32, maColorModeBit | - maModeIsSupportedBit | - maGraphicsModeBit | - maLinearFrameBufferAvailBit, - 0, - &minfo, &vesaVersion ); + /* + * AutoResolution + */ + if (autoResolution == TRUE) {//Get Resolution from Graphics Mode key + count = getNumberArrayFromProperty(kGraphicsModeKey, screen_params, 4); + if ( count < 3 ) { + //If no Graphics Mode key, get it from EDID + getResolution(&screen_params[0], &screen_params[1], &screen_params[2]); + } } else { // parse screen size parameters if(getIntForKey("screen_width", &val, &bootInfo->themeConfig)) @@ -768,6 +767,10 @@ dprintf( &gui.screen, "name %s\n", param->name ); dprintf( &gui.screen, "type_name %s\n", param->type_name ); dprintf( &gui.screen, "modtime %d\n", param->modTime ); + dprintf(&gui.screen, "width %d\n", gui.screen.width); + dprintf(&gui.screen, "height %d\n", gui.screen.height); + dprintf(&gui.screen, "attr: 0x%x\n", gui.screen.attr); + dprintf(&gui.screen, "mm: %d\n", gui.screen.mm); #endif } @@ -1706,7 +1709,7 @@ void drawBootGraphics(void) { int pos; - int length; + int length, count; const char *dummyVal; bool legacy_logo; uint16_t x, y; @@ -1717,18 +1720,19 @@ loadBootGraphics(); } - if (autoResolution == TRUE) { - VBEModeInfoBlock minfo; - unsigned short mode_n; - unsigned short vesaVersion; - - mode_n = getVESAModeWithProperties( screen_params[0], screen_params[1], 32, maColorModeBit | - maModeIsSupportedBit | - maGraphicsModeBit | - maLinearFrameBufferAvailBit, - 0, - &minfo, &vesaVersion ); - } else { + /* + * AutoResolution + */ + if (autoResolution == TRUE) { + //Get Resolution from Graphics Mode key + count = getNumberArrayFromProperty(kGraphicsModeKey, screen_params, 4); + if ( count < 3 ) { + //If no Graphics Mode key, get resolution from EDID + getResolution(&screen_params[0], &screen_params[1], &screen_params[2]); + } + + + } else { // parse screen size parameters if(getIntForKey("boot_width", &pos, &bootInfo->themeConfig)) screen_params[0] = pos; Index: branches/diebuche/i386/boot2/gui.h =================================================================== --- branches/diebuche/i386/boot2/gui.h (revision 131) +++ branches/diebuche/i386/boot2/gui.h (revision 132) @@ -96,6 +96,15 @@ uint32_t font_small_color; // Color for small font AARRGGBB uint32_t font_console_color; // Color for consle font AARRGGBB bool draw; // Draw flag + //resolution specifics + uint16_t htotal; + uint16_t vtotal; + uint16_t hsyncstart; + uint16_t hsyncend; + uint16_t vsyncstart; + uint16_t vsyncend; + uint8_t mm; + uint16_t attr; } window_t; /*