source: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/i915resolution.c @ 26ffad7

Last change on this file since 26ffad7 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 20.7 KB
Line 
1/* ----------------------------------------------------------------------- *
2 *   
3 *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
4 *
5 *   Permission is hereby granted, free of charge, to any person
6 *   obtaining a copy of this software and associated documentation
7 *   files (the "Software"), to deal in the Software without
8 *   restriction, including without limitation the rights to use,
9 *   copy, modify, merge, publish, distribute, sublicense, and/or
10 *   sell copies of the Software, and to permit persons to whom
11 *   the Software is furnished to do so, subject to the following
12 *   conditions:
13 *   
14 *   The above copyright notice and this permission notice shall
15 *   be included in all copies or substantial portions of the Software.
16 *   
17 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 *   OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * ----------------------------------------------------------------------- */
27
28/*
29 * Based on:
30 *
31 * 915 resolution by steve tomljenovic
32 *
33 * This was tested only on Sony VGN-FS550.  Use at your own risk
34 *
35 * This code is based on the techniques used in :
36 *
37 *   - 855patch.  Many thanks to Christian Zietz (czietz gmx net)
38 *     for demonstrating how to shadow the VBIOS into system RAM
39 *     and then modify it.
40 *
41 *   - 1280patch by Andrew Tipton (andrewtipton null li).
42 *
43 *   - 855resolution by Alain Poirier
44 *
45 * This source code is into the public domain.
46 */
47
48#include <stdio.h>
49#include <stdlib.h>
50#include <unistd.h>
51#define __USE_GNU
52#include <string.h>
53#include <sys/io.h>
54#include <sys/cpu.h>
55#include <sys/pci.h>
56#include <unistd.h>
57#include <assert.h>
58#include <stdbool.h>
59#include "video.h"
60#include "debug.h"
61
62#define VBIOS_START         0xc0000
63#define VBIOS_SIZE          0x10000
64
65#define MODE_TABLE_OFFSET_845G 617
66
67#define VERSION "0.5.3"
68
69#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
70#define ATI_SIGNATURE2 "ATI Technologies Inc"
71#define NVIDIA_SIGNATURE "NVIDIA Corp"
72#define INTEL_SIGNATURE "Intel Corp"
73
74typedef unsigned char * address;
75
76typedef enum {
77    CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM,
78    CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME,
79    CHIPSET_TYPES
80} chipset_type;
81
82typedef enum {
83    BT_UNKWN, BT_1, BT_2, BT_3
84} bios_type;
85
86static int freqs[] = { 60, 75, 85 };
87
88typedef struct {
89    uint8_t mode;
90    uint8_t bits_per_pixel;
91    uint16_t resolution;
92    uint8_t unknown;
93} __attribute__((packed)) vbios_mode;
94
95typedef struct {
96    uint16_t clock;             /* Clock frequency in 10 kHz */
97    uint8_t x1;
98    uint8_t x_total;
99    uint8_t x2;
100    uint8_t y1;
101    uint8_t y_total;
102    uint8_t y2;
103} __attribute__((packed)) vbios_resolution_type1;
104
105typedef struct {
106    uint32_t clock;
107
108    uint16_t x1;
109    uint16_t htotal;
110    uint16_t x2;
111    uint16_t hblank;
112    uint16_t hsyncstart;
113    uint16_t hsyncend;
114
115    uint16_t y1;
116    uint16_t vtotal;
117    uint16_t y2;
118    uint16_t vblank;
119    uint16_t vsyncstart;
120    uint16_t vsyncend;
121} __attribute__((packed)) vbios_modeline_type2;
122
123typedef struct {
124    uint8_t xchars;
125    uint8_t ychars;
126    uint8_t unknown[4];
127
128    vbios_modeline_type2 modelines[];
129} __attribute__((packed)) vbios_resolution_type2;
130
131typedef struct {
132    uint32_t clock;
133
134    uint16_t x1;
135    uint16_t htotal;
136    uint16_t x2;
137    uint16_t hblank;
138    uint16_t hsyncstart;
139    uint16_t hsyncend;
140
141    uint16_t y1;
142    uint16_t vtotal;
143    uint16_t y2;
144    uint16_t vblank;
145    uint16_t vsyncstart;
146    uint16_t vsyncend;
147
148    uint16_t timing_h;
149    uint16_t timing_v;
150
151    uint8_t unknown[6];
152} __attribute__((packed)) vbios_modeline_type3;
153
154typedef struct {
155    unsigned char unknown[6];
156
157    vbios_modeline_type3 modelines[];
158} __attribute__((packed)) vbios_resolution_type3;
159
160
161typedef struct {
162    unsigned int chipset_id;
163    chipset_type chipset;
164    bios_type bios;
165   
166    address bios_ptr;
167
168    vbios_mode * mode_table;
169    unsigned int mode_table_size;
170
171    uint8_t b1, b2;
172
173    bool unlocked;
174} vbios_map;
175
176#if 0                           /* Debugging hacks */
177static void good_marker(int x)
178{
179    ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f);
180}
181
182static void bad_marker(int x)
183{
184    ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f);
185}
186
187static void status(const char *fmt, ...)
188{
189    va_list ap;
190    char msg[81], *p;
191    int i;
192    uint16_t *q;
193
194    memset(msg, 0, sizeof msg);
195    va_start(ap, fmt);
196    vsnprintf(msg, sizeof msg, fmt, ap);
197    va_end(ap);
198    p = msg;
199    q = (uint16_t *)0xb8000 + 80;
200    for (i = 0; i < 80; i++)
201        *q++ = *p++ + 0x1f00;
202}
203#else
204static inline void good_marker(int x) { (void)x; }
205static inline void bad_marker(int x) { (void)x; }
206static inline void status(const char *fmt, ...) { (void)fmt; }
207#endif
208
209static unsigned int get_chipset_id(void) {
210    return pci_readl(0x80000000);
211}
212
213static chipset_type get_chipset(unsigned int id) {
214    chipset_type type;
215
216    switch (id) {
217    case 0x35758086:
218        type = CT_830;
219        break;
220
221    case 0x25608086:
222        type = CT_845G;
223        break;
224       
225    case 0x35808086:
226        type = CT_855GM;
227        break;
228       
229    case 0x25708086:
230        type = CT_865G;
231        break;
232
233    case 0x25808086:
234        type = CT_915G;
235        break;
236
237    case 0x25908086:
238        type = CT_915GM;
239        break;
240
241    case 0x27708086:
242        type = CT_945G;
243        break;
244
245    case 0x27a08086:
246        type = CT_945GM;
247        break;
248
249    case 0x29708086:
250        type = CT_946GZ;
251        break;
252
253    case 0x29a08086:
254        type = CT_G965;
255        break;
256
257    case 0x29908086:
258        type = CT_Q965;
259        break;
260
261    case 0x27ac8086:
262        type = CT_945GME;
263        break;
264
265    default:
266        type = CT_UNKWN;
267        break;
268    }
269
270    return type;
271}
272
273
274static vbios_resolution_type1 * map_type1_resolution(vbios_map * map,
275                                                     uint16_t res)
276{
277    vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
278    return ptr;
279}
280
281static vbios_resolution_type2 * map_type2_resolution(vbios_map * map,
282                                                     uint16_t res)
283{
284    vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
285    return ptr;
286}
287
288static vbios_resolution_type3 * map_type3_resolution(vbios_map * map,
289                                                     uint16_t res)
290{
291    vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
292    return ptr;
293}
294
295
296static bool detect_bios_type(vbios_map * map, int entry_size)
297{
298    unsigned int i;
299    uint16_t r1, r2;
300   
301    r1 = r2 = 32000;
302
303    for (i = 0; i < map->mode_table_size; i++) {
304        if (map->mode_table[i].resolution <= r1) {
305            r1 = map->mode_table[i].resolution;
306        } else if (map->mode_table[i].resolution <= r2) {
307            r2 = map->mode_table[i].resolution;
308        }
309    }
310   
311    return ((r2-r1-6) % entry_size) == 0;
312}
313
314static inline void close_vbios(vbios_map *map)
315{
316    (void)map;
317}
318
319static vbios_map * open_vbios(void)
320{
321    static vbios_map _map;
322    vbios_map * const map = &_map;
323
324    memset(&_map, 0, sizeof _map);
325
326    /*
327     * Determine chipset
328     */
329    map->chipset_id = get_chipset_id();
330    good_marker(0x10);
331    map->chipset = get_chipset(map->chipset_id);
332    good_marker(0x11);
333
334    /*
335     *  Map the video bios to memory
336     */
337    map->bios_ptr = (void *)VBIOS_START;
338
339    /*
340     * check if we have ATI Radeon
341     */
342   
343    if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
344        memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
345        debug("ATI chipset detected.  915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
346        return NULL;
347    }
348
349    /*
350     * check if we have NVIDIA
351     */
352   
353    if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) {
354        debug("NVIDIA chipset detected.  915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
355        return NULL;
356    }
357
358    /*
359     * check if we have Intel
360     */
361   
362    if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
363        debug("Intel chipset detected.  However, 915resolution was unable to determine the chipset type.\r\n");
364
365        debug("Chipset Id: %x\r\n", map->chipset_id);
366
367        debug("Please report this problem to stomljen@yahoo.com\r\n");
368       
369        close_vbios(map);
370        return NULL;
371    }
372
373    /*
374     * check for others
375     */
376
377    if (map->chipset == CT_UNKWN) {
378        debug("Unknown chipset type and unrecognized bios.\r\n");
379        debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
380
381        debug("Chipset Id: %x\r\n", map->chipset_id);
382        close_vbios(map);
383        return NULL;
384    }
385
386    /*
387     * Figure out where the mode table is
388     */
389    good_marker(0x12);
390
391    {
392        address p = map->bios_ptr + 16;
393        address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
394       
395        while (p < limit && map->mode_table == 0) {
396            vbios_mode * mode_ptr = (vbios_mode *) p;
397           
398            if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
399                ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
400
401                map->mode_table = mode_ptr;
402            }
403           
404            p++;
405        }
406
407        if (map->mode_table == 0) {
408            debug("Unable to locate the mode table.\r\n");
409            close_vbios(map);
410            return NULL;
411        }
412    }
413    good_marker(0x13);
414
415    /*
416     * Determine size of mode table
417     */
418   
419    {
420        vbios_mode * mode_ptr = map->mode_table;
421       
422        while (mode_ptr->mode != 0xff) {
423            map->mode_table_size++;
424            mode_ptr++;
425        }
426    }
427    good_marker(0x14);
428    status("mode_table_size = %d", map->mode_table_size);
429
430    /*
431     * Figure out what type of bios we have
432     *  order of detection is important
433     */
434
435    if (detect_bios_type(map, sizeof(vbios_modeline_type3))) {
436        map->bios = BT_3;
437    }
438    else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) {
439        map->bios = BT_2;
440    }
441    else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) {
442        map->bios = BT_1;
443    }
444    else {
445        debug("Unable to determine bios type.\r\n");
446        debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
447        debug("Mode Table Entries: %u\r\n", map->mode_table_size);
448        bad_marker(0x15);
449        return NULL;
450    }
451    good_marker(0x15);
452
453    return map;
454}
455
456static void unlock_vbios(vbios_map * map)
457{
458    assert(!map->unlocked);
459
460    map->unlocked = true;
461   
462    switch (map->chipset) {
463    case CT_UNKWN:
464    case CHIPSET_TYPES:         /* Shut up gcc */
465        break;
466    case CT_830:
467    case CT_855GM:
468        map->b1 = pci_readb(0x8000005a);
469        pci_writeb(0x33, 0x8000005a);
470        break;
471    case CT_845G:
472    case CT_865G:
473    case CT_915G:
474    case CT_915GM:
475    case CT_945G:
476    case CT_945GM:
477    case CT_945GME:
478    case CT_946GZ:
479    case CT_G965:
480    case CT_Q965:
481        map->b1 = pci_readb(0x80000091);
482        map->b2 = pci_readb(0x80000092);
483        pci_writeb(0x33, 0x80000091);
484        pci_writeb(0x33, 0x80000092);
485        break;
486    }
487
488#if DEBUG
489    {
490        unsigned int t = inl(0xcfc);
491        debug("unlock PAM: (0x%08x)\r\n", t);
492    }
493#endif
494}
495
496static void relock_vbios(vbios_map * map)
497{
498    assert(map->unlocked);
499    map->unlocked = false;
500   
501    switch (map->chipset) {
502    case CT_UNKWN:
503    case CHIPSET_TYPES:         /* Shut up gcc */
504        break;
505    case CT_830:
506    case CT_855GM:
507        pci_writeb(map->b1, 0x8000005a);
508        break;
509    case CT_845G:
510    case CT_865G:
511    case CT_915G:
512    case CT_915GM:
513    case CT_945G:
514    case CT_945GM:
515    case CT_945GME:
516    case CT_946GZ:
517    case CT_G965:
518    case CT_Q965:
519        pci_writeb(map->b1, 0x80000091);
520        pci_writeb(map->b2, 0x80000092);
521        break;
522    }
523
524#if DEBUG
525    {
526        unsigned int t = inl(0xcfc);
527        debug("relock PAM: (0x%08x)\r\n", t);
528    }
529#endif
530}
531
532#if 0
533static void list_modes(vbios_map *map, unsigned int raw)
534{
535    unsigned int i, x, y;
536
537    for (i=0; i < map->mode_table_size; i++) {
538        switch(map->bios) {
539        case BT_1:
540            {
541                vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
542               
543                x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1;
544                y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1;
545               
546                if (x != 0 && y != 0) {
547                    debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
548                }
549
550                if (raw)
551                {
552                    debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
553                }
554
555            }
556            break;
557        case BT_2:
558            {
559                vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
560               
561                x = res->modelines[0].x1+1;
562                y = res->modelines[0].y1+1;
563
564                if (x != 0 && y != 0) {
565                    debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
566                }
567            }
568            break;
569        case BT_3:
570            {
571                vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
572               
573                x = res->modelines[0].x1+1;
574                y = res->modelines[0].y1+1;
575               
576                if (x != 0 && y != 0) {
577                    debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
578                }
579            }
580            break;
581        case BT_UNKWN:
582            break;
583        }
584    }
585}
586#endif
587
588static void gtf_timings(int x, int y, int freq, uint32_t *clock,
589        uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank,
590        uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank)
591{
592    int hbl, vbl, vfreq;
593
594    vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
595    vfreq = vbl * freq;
596    hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
597            (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
598
599    *vsyncstart = y;
600    *vsyncend = y + 3;
601    *vblank = vbl - 1;
602    *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
603    *hsyncend = x + hbl / 2 - 1;
604    *hblank = x + hbl - 1;
605    *clock = (x + hbl) * vfreq / 1000;
606}
607
608static int set_mode(vbios_map * map, unsigned int mode,
609                     unsigned int x, unsigned int y, unsigned int bp,
610                     unsigned int htotal, unsigned int vtotal)
611{
612    int xprev, yprev;
613    unsigned int i, j;
614    int rv = -1;
615
616    for (i=0; i < map->mode_table_size; i++) {
617        if (map->mode_table[i].mode == mode) {
618            switch(map->bios) {
619            case BT_1:
620                {
621                    vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
622                    uint32_t clock;
623                    uint16_t hsyncstart, hsyncend, hblank;
624                    uint16_t vsyncstart, vsyncend, vblank;
625                   
626                    if (bp) {
627                        map->mode_table[i].bits_per_pixel = bp;
628                    }
629
630                    gtf_timings(x, y, freqs[0], &clock,
631                                &hsyncstart, &hsyncend, &hblank,
632                                &vsyncstart, &vsyncend, &vblank);
633                   
634                    status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n",
635                          x, y, clock,
636                          hsyncstart, hsyncend, hblank,
637                          vsyncstart, vsyncend, vblank);
638
639                    htotal = htotal ? htotal : (unsigned int)hblank+1;
640                    vtotal = vtotal ? vtotal : (unsigned int)vblank+1;
641
642                    res->clock = clock/10; /* Units appear to be 10 kHz */
643                    res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0);
644                    res->x1 = (x & 0xff);
645                   
646                    res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0);
647                    res->y1 = (y & 0xff);
648                    if (htotal)
649                        res->x_total = ((htotal-x) & 0xff);
650
651                    if (vtotal)
652                        res->y_total = ((vtotal-y) & 0xff);
653
654                    rv = 0;
655                }
656                break;
657            case BT_2:
658                {
659                    vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
660
661                    res->xchars = x / 8;
662                    res->ychars = y / 16 - 1;
663                    xprev = res->modelines[0].x1;
664                    yprev = res->modelines[0].y1;
665
666                    for(j=0; j < 3; j++) {
667                        vbios_modeline_type2 * modeline = &res->modelines[j];
668                       
669                        if (modeline->x1 == xprev && modeline->y1 == yprev) {
670                            modeline->x1 = modeline->x2 = x-1;
671                            modeline->y1 = modeline->y2 = y-1;
672
673                            gtf_timings(x, y, freqs[j], &modeline->clock,
674                                    &modeline->hsyncstart, &modeline->hsyncend,
675                                    &modeline->hblank, &modeline->vsyncstart,
676                                    &modeline->vsyncend, &modeline->vblank);
677
678                            if (htotal)
679                                modeline->htotal = htotal;
680                            else
681                                modeline->htotal = modeline->hblank;
682
683                            if (vtotal)
684                                modeline->vtotal = vtotal;
685                            else
686                                modeline->vtotal = modeline->vblank;
687                        }
688                    }
689
690                    rv = 0;
691                }
692                break;
693            case BT_3:
694                {
695                    vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
696                   
697                    xprev = res->modelines[0].x1;
698                    yprev = res->modelines[0].y1;
699
700                    for (j=0; j < 3; j++) {
701                        vbios_modeline_type3 * modeline = &res->modelines[j];
702                       
703                        if (modeline->x1 == xprev && modeline->y1 == yprev) {
704                            modeline->x1 = modeline->x2 = x-1;
705                            modeline->y1 = modeline->y2 = y-1;
706                           
707                            gtf_timings(x, y, freqs[j], &modeline->clock,
708                                    &modeline->hsyncstart, &modeline->hsyncend,
709                                    &modeline->hblank, &modeline->vsyncstart,
710                                    &modeline->vsyncend, &modeline->vblank);
711                            if (htotal)
712                                modeline->htotal = htotal;
713                            else
714                                modeline->htotal = modeline->hblank;
715                            if (vtotal)
716                                modeline->vtotal = vtotal;
717                            else
718                                modeline->vtotal = modeline->vblank;
719
720                            modeline->timing_h   = y-1;
721                            modeline->timing_v   = x-1;
722                        }
723                    }
724
725                    rv = 0;
726                }
727                break;
728            case BT_UNKWN:
729                break;
730            }
731        }
732    }
733
734    return rv;
735}   
736
737static inline void display_map_info(vbios_map * map) {
738#ifdef DEBUG
739    static const char * bios_type_names[] =
740        {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
741    static const char * chipset_type_names[] = {
742        "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G",
743        "945GM", "946GZ", "G965", "Q965", "945GME"
744    };
745
746    debug("Chipset: %s\r\n", chipset_type_names[map->chipset]);
747    debug("BIOS: %s\r\n", bios_type_names[map->bios]);
748
749    debug("Mode Table Offset: $C0000 + $%x\r\n",
750          ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
751    debug("Mode Table Entries: %u\r\n", map->mode_table_size);
752#endif
753    (void)map;
754}
755
756int __vesacon_i915resolution(int x, int y)
757{
758    vbios_map * map;
759    unsigned int mode = 0x52;   /* 800x600x32 mode in known BIOSes */
760    unsigned int bp = 32;       /* 32 bits per pixel */
761    int rv = 0;
762
763    good_marker(0);
764
765    map = open_vbios();
766    if (!map)
767        return -1;
768
769    good_marker(1);
770
771    display_map_info(map);
772
773    debug("\r\n");
774
775    if (mode && x && y) {
776        good_marker(2);
777        cli();
778        good_marker(3);
779        unlock_vbios(map);
780        good_marker(4);
781        rv = set_mode(map, mode, x, y, bp, 0, 0);
782        if (rv)
783            bad_marker(5);
784        else
785            good_marker(5);
786        relock_vbios(map);
787        good_marker(6);
788        sti();
789       
790        debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y);
791    }
792    close_vbios(map);
793   
794    return rv;
795}
Note: See TracBrowser for help on using the repository browser.