|
|
1.1 root 1: // Hooks for via vgabios calls into main bios.
2: //
3: // Copyright (C) 2008 Kevin O'Connor <[email protected]>
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()
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: u32 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.