~ubuntu-branches/ubuntu/oneiric/seabios/oneiric

« back to all changes in this revision

Viewing changes to .pc/0037-SeaBIOS-VGA-hooks.patch/src/vgahooks.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2010-10-22 11:04:31 UTC
  • Revision ID: james.westby@ubuntu.com-20101022110431-fnfj73ra6xkq623n
Tags: 0.6.0-0ubuntu2
Add all patches which were included in qemu-0.13.0-rc2 (per
commit on Jul 13, 2010).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Hooks for via vgabios calls into main bios.
 
2
//
 
3
// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
 
4
//
 
5
// This file may be distributed under the terms of the GNU LGPLv3 license.
 
6
 
 
7
#include "bregs.h" // set_code_invalid
 
8
#include "biosvar.h" // GET_GLOBAL
 
9
#include "pci.h" // pci_find_device
 
10
#include "pci_regs.h" // PCI_VENDOR_ID
 
11
#include "pci_ids.h" // PCI_VENDOR_ID_VIA
 
12
#include "util.h" // handle_155f
 
13
#include "config.h" // CONFIG_*
 
14
 
 
15
// The Bus/Dev/Fn of the primary VGA device.
 
16
int VGAbdf VAR16VISIBLE;
 
17
// Coreboot board detected.
 
18
int CBmainboard VAR16VISIBLE;
 
19
 
 
20
static void
 
21
handle_155fXX(struct bregs *regs)
 
22
{
 
23
    set_code_unimplemented(regs, RET_EUNSUPPORTED);
 
24
}
 
25
 
 
26
 
 
27
/****************************************************************
 
28
 * Via hooks
 
29
 ****************************************************************/
 
30
 
 
31
static void
 
32
via_155f01(struct bregs *regs)
 
33
{
 
34
    regs->eax = 0x5f;
 
35
    regs->cl = 2; // panel type =  2 = 1024 * 768
 
36
    set_success(regs);
 
37
    dprintf(1, "Warning: VGA panel type is hardcoded\n");
 
38
}
 
39
 
 
40
static void
 
41
via_155f02(struct bregs *regs)
 
42
{
 
43
    regs->eax = 0x5f;
 
44
    regs->bx = 2;
 
45
    regs->cx = 0x401;  // PAL + crt only
 
46
    regs->dx = 0;  // TV Layout - default
 
47
    set_success(regs);
 
48
    dprintf(1, "Warning: VGA TV/CRT output type is hardcoded\n");
 
49
}
 
50
 
 
51
static int
 
52
getFBSize(u16 bdf)
 
53
{
 
54
    /* FB config */
 
55
    u8 reg = pci_config_readb(bdf, 0xa1);
 
56
 
 
57
    /* GFX disabled ? */
 
58
    if (!(reg & 0x80))
 
59
        return -1;
 
60
 
 
61
    static u8 mem_power[] VAR16 = {0, 3, 4, 5, 6, 7, 8, 9};
 
62
    return GET_GLOBAL(mem_power[(reg >> 4) & 0x7]);
 
63
}
 
64
 
 
65
static int
 
66
getViaRamSpeed(u16 bdf)
 
67
{
 
68
    return (pci_config_readb(bdf, 0x90) & 0x07) + 3;
 
69
}
 
70
 
 
71
static int
 
72
getAMDRamSpeed(void)
 
73
{
 
74
    int bdf = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL);
 
75
    if (bdf < 0)
 
76
        return -1;
 
77
 
 
78
    /* mem clk 0 = DDR2 400 */
 
79
    return (pci_config_readb(bdf, 0x94) & 0x7) + 6;
 
80
}
 
81
 
 
82
/* int 0x15 - 5f18
 
83
 
 
84
   ECX = unknown/dont care
 
85
   EBX[3..0] Frame Buffer Size 2^N MiB
 
86
   EBX[7..4] Memory speed:
 
87
       0: SDR  66Mhz
 
88
       1: SDR 100Mhz
 
89
       2: SDR 133Mhz
 
90
       3: DDR 100Mhz (PC1600 or DDR200)
 
91
       4: DDR 133Mhz (PC2100 or DDR266)
 
92
       5: DDR 166Mhz (PC2700 or DDR333)
 
93
       6: DDR 200Mhz (PC3200 or DDR400)
 
94
       7: DDR2 133Mhz (DDR2 533)
 
95
       8: DDR2 166Mhz (DDR2 667)
 
96
       9: DDR2 200Mhz (DDR2 800)
 
97
       A: DDR2 233Mhz (DDR2 1066)
 
98
       B: and above: Unknown
 
99
   EBX[?..8] Total memory size?
 
100
   EAX = 0x5f for success
 
101
*/
 
102
 
 
103
#define PCI_DEVICE_ID_VIA_K8M890CE_3    0x3336
 
104
#define PCI_DEVICE_ID_VIA_VX855_MEMCTRL 0x3409
 
105
 
 
106
static void
 
107
via_155f18(struct bregs *regs)
 
108
{
 
109
    int ramspeed, fbsize;
 
110
 
 
111
    int bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3);
 
112
    if (bdf >= 0) {
 
113
        fbsize = getFBSize(bdf);
 
114
        ramspeed = getAMDRamSpeed();
 
115
        goto done;
 
116
    }
 
117
    bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_MEMCTRL);
 
118
    if (bdf >= 0) {
 
119
        fbsize = getFBSize(bdf);
 
120
        ramspeed = getViaRamSpeed(bdf);
 
121
        goto done;
 
122
    }
 
123
 
 
124
    dprintf(1, "Warning: VGA memory size and speed is hardcoded\n");
 
125
    fbsize = 5; // 32M frame buffer
 
126
    ramspeed = 4; // MCLK = DDR266
 
127
 
 
128
done:
 
129
    if (fbsize < 0 || ramspeed < 0) {
 
130
        set_code_invalid(regs, RET_EUNSUPPORTED);
 
131
        return;
 
132
    }
 
133
    regs->eax = 0x5f;
 
134
    regs->ebx = 0x500 | (ramspeed << 4) | fbsize;
 
135
    regs->ecx = 0x060;
 
136
    set_success(regs);
 
137
}
 
138
 
 
139
static void
 
140
via_155f19(struct bregs *regs)
 
141
{
 
142
    set_invalid_silent(regs);
 
143
}
 
144
 
 
145
static void
 
146
via_155f(struct bregs *regs)
 
147
{
 
148
    switch (regs->al) {
 
149
    case 0x01: via_155f01(regs); break;
 
150
    case 0x02: via_155f02(regs); break;
 
151
    case 0x18: via_155f18(regs); break;
 
152
    case 0x19: via_155f19(regs); break;
 
153
    default:   handle_155fXX(regs); break;
 
154
    }
 
155
}
 
156
 
 
157
 
 
158
/****************************************************************
 
159
 * Entry and setup
 
160
 ****************************************************************/
 
161
 
 
162
// Main 16bit entry point
 
163
void
 
164
handle_155f(struct bregs *regs)
 
165
{
 
166
    if (! CONFIG_VGAHOOKS)
 
167
        goto fail;
 
168
 
 
169
    // XXX - Use this value later.
 
170
    //int cbmb = GET_GLOBAL(CBmainboard);
 
171
 
 
172
    int bdf = GET_GLOBAL(VGAbdf);
 
173
    if (bdf < 0)
 
174
        goto fail;
 
175
    u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
 
176
    if (vendor == PCI_VENDOR_ID_VIA) {
 
177
        via_155f(regs);
 
178
        return;
 
179
    }
 
180
 
 
181
fail:
 
182
    handle_155fXX(regs);
 
183
}
 
184
 
 
185
// Setup
 
186
void
 
187
vgahook_setup(const char *vendor, const char *part)
 
188
{
 
189
    if (! CONFIG_VGAHOOKS)
 
190
        return;
 
191
    // XXX - add support later.
 
192
    CBmainboard = 0;
 
193
}