|
|
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:
1.1.1.3 ! root 20: #define MAINBOARD_DEFAULT 0
! 21: #define KONTRON_986LCD_M 1
! 22: #define GETAC_P470 2
! 23: #define RODA_RK886EX 3
! 24:
! 25: struct mainboards {
! 26: char *vendor;
! 27: char *device;
! 28: int type;
! 29: };
! 30:
! 31: struct mainboards mainboard_list[] = {
! 32: { "KONTRON", "986LCD-M", KONTRON_986LCD_M },
! 33: { "GETAC", "P470", GETAC_P470 },
! 34: { "RODA", "RK886EX", RODA_RK886EX },
! 35: };
! 36:
1.1 root 37: static void
38: handle_155fXX(struct bregs *regs)
39: {
40: set_code_unimplemented(regs, RET_EUNSUPPORTED);
41: }
42:
43:
44: /****************************************************************
45: * Via hooks
46: ****************************************************************/
47:
48: static void
49: via_155f01(struct bregs *regs)
50: {
51: regs->eax = 0x5f;
52: regs->cl = 2; // panel type = 2 = 1024 * 768
53: set_success(regs);
54: dprintf(1, "Warning: VGA panel type is hardcoded\n");
55: }
56:
57: static void
58: via_155f02(struct bregs *regs)
59: {
60: regs->eax = 0x5f;
61: regs->bx = 2;
62: regs->cx = 0x401; // PAL + crt only
63: regs->dx = 0; // TV Layout - default
64: set_success(regs);
65: dprintf(1, "Warning: VGA TV/CRT output type is hardcoded\n");
66: }
67:
68: static int
69: getFBSize(u16 bdf)
70: {
71: /* FB config */
72: u8 reg = pci_config_readb(bdf, 0xa1);
73:
74: /* GFX disabled ? */
75: if (!(reg & 0x80))
76: return -1;
77:
78: static u8 mem_power[] VAR16 = {0, 3, 4, 5, 6, 7, 8, 9};
79: return GET_GLOBAL(mem_power[(reg >> 4) & 0x7]);
80: }
81:
82: static int
83: getViaRamSpeed(u16 bdf)
84: {
85: return (pci_config_readb(bdf, 0x90) & 0x07) + 3;
86: }
87:
88: static int
1.1.1.2 root 89: getAMDRamSpeed(void)
1.1 root 90: {
91: int bdf = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL);
92: if (bdf < 0)
93: return -1;
94:
95: /* mem clk 0 = DDR2 400 */
96: return (pci_config_readb(bdf, 0x94) & 0x7) + 6;
97: }
98:
99: /* int 0x15 - 5f18
100:
101: ECX = unknown/dont care
102: EBX[3..0] Frame Buffer Size 2^N MiB
103: EBX[7..4] Memory speed:
104: 0: SDR 66Mhz
105: 1: SDR 100Mhz
106: 2: SDR 133Mhz
107: 3: DDR 100Mhz (PC1600 or DDR200)
108: 4: DDR 133Mhz (PC2100 or DDR266)
109: 5: DDR 166Mhz (PC2700 or DDR333)
110: 6: DDR 200Mhz (PC3200 or DDR400)
111: 7: DDR2 133Mhz (DDR2 533)
112: 8: DDR2 166Mhz (DDR2 667)
113: 9: DDR2 200Mhz (DDR2 800)
114: A: DDR2 233Mhz (DDR2 1066)
115: B: and above: Unknown
116: EBX[?..8] Total memory size?
117: EAX = 0x5f for success
118: */
119:
120: #define PCI_DEVICE_ID_VIA_K8M890CE_3 0x3336
121: #define PCI_DEVICE_ID_VIA_VX855_MEMCTRL 0x3409
122:
123: static void
124: via_155f18(struct bregs *regs)
125: {
1.1.1.2 root 126: int ramspeed, fbsize;
1.1 root 127:
128: int bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3);
129: if (bdf >= 0) {
130: fbsize = getFBSize(bdf);
131: ramspeed = getAMDRamSpeed();
132: goto done;
133: }
134: bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_MEMCTRL);
135: if (bdf >= 0) {
136: fbsize = getFBSize(bdf);
137: ramspeed = getViaRamSpeed(bdf);
138: goto done;
139: }
140:
141: dprintf(1, "Warning: VGA memory size and speed is hardcoded\n");
142: fbsize = 5; // 32M frame buffer
143: ramspeed = 4; // MCLK = DDR266
144:
145: done:
146: if (fbsize < 0 || ramspeed < 0) {
147: set_code_invalid(regs, RET_EUNSUPPORTED);
148: return;
149: }
150: regs->eax = 0x5f;
151: regs->ebx = 0x500 | (ramspeed << 4) | fbsize;
152: regs->ecx = 0x060;
153: set_success(regs);
154: }
155:
156: static void
157: via_155f19(struct bregs *regs)
158: {
159: set_invalid_silent(regs);
160: }
161:
162: static void
163: via_155f(struct bregs *regs)
164: {
165: switch (regs->al) {
166: case 0x01: via_155f01(regs); break;
167: case 0x02: via_155f02(regs); break;
168: case 0x18: via_155f18(regs); break;
169: case 0x19: via_155f19(regs); break;
170: default: handle_155fXX(regs); break;
171: }
172: }
173:
1.1.1.3 ! root 174: /****************************************************************
! 175: * Intel VGA hooks
! 176: ****************************************************************/
! 177: #define BOOT_DISPLAY_DEFAULT (0)
! 178: #define BOOT_DISPLAY_CRT (1 << 0)
! 179: #define BOOT_DISPLAY_TV (1 << 1)
! 180: #define BOOT_DISPLAY_EFP (1 << 2)
! 181: #define BOOT_DISPLAY_LCD (1 << 3)
! 182: #define BOOT_DISPLAY_CRT2 (1 << 4)
! 183: #define BOOT_DISPLAY_TV2 (1 << 5)
! 184: #define BOOT_DISPLAY_EFP2 (1 << 6)
! 185: #define BOOT_DISPLAY_LCD2 (1 << 7)
! 186:
! 187: static void
! 188: roda_155f35(struct bregs *regs)
! 189: {
! 190: regs->ax = 0x005f;
! 191: // regs->cl = BOOT_DISPLAY_DEFAULT;
! 192: regs->cl = BOOT_DISPLAY_LCD;
! 193: set_success(regs);
! 194: }
! 195:
! 196: static void
! 197: roda_155f40(struct bregs *regs)
! 198: {
! 199: u8 display_id;
! 200: //display_id = inb(0x60f) & 0x0f; // Correct according to Crete
! 201: display_id = 3; // Correct according to empirical studies
! 202:
! 203: regs->ax = 0x005f;
! 204: regs->cl = display_id;
! 205: set_success(regs);
! 206: }
! 207:
! 208: static void
! 209: roda_155f(struct bregs *regs)
! 210: {
! 211: dprintf(1, "Executing RODA specific interrupt %02x.\n", regs->al);
! 212: switch (regs->al) {
! 213: case 0x35: roda_155f35(regs); break;
! 214: case 0x40: roda_155f40(regs); break;
! 215: default: handle_155fXX(regs); break;
! 216: }
! 217: }
! 218:
! 219: static void
! 220: kontron_155f35(struct bregs *regs)
! 221: {
! 222: regs->ax = 0x005f;
! 223: regs->cl = BOOT_DISPLAY_CRT;
! 224: set_success(regs);
! 225: }
! 226:
! 227: static void
! 228: kontron_155f40(struct bregs *regs)
! 229: {
! 230: u8 display_id;
! 231: display_id = 3;
! 232:
! 233: regs->ax = 0x005f;
! 234: regs->cl = display_id;
! 235: set_success(regs);
! 236: }
! 237:
! 238: static void
! 239: kontron_155f(struct bregs *regs)
! 240: {
! 241: dprintf(1, "Executing Kontron specific interrupt %02x.\n", regs->al);
! 242: switch (regs->al) {
! 243: case 0x35: kontron_155f35(regs); break;
! 244: case 0x40: kontron_155f40(regs); break;
! 245: default: handle_155fXX(regs); break;
! 246: }
! 247: }
! 248:
! 249: static void
! 250: getac_155f(struct bregs *regs)
! 251: {
! 252: dprintf(1, "Executing Getac specific interrupt %02x.\n", regs->al);
! 253: switch (regs->al) {
! 254: default: handle_155fXX(regs); break;
! 255: }
! 256: }
1.1 root 257:
258: /****************************************************************
259: * Entry and setup
260: ****************************************************************/
261:
262: // Main 16bit entry point
263: void
264: handle_155f(struct bregs *regs)
265: {
1.1.1.3 ! root 266: int bdf, cbmb;
! 267:
1.1 root 268: if (! CONFIG_VGAHOOKS)
269: goto fail;
270:
1.1.1.3 ! root 271: cbmb = GET_GLOBAL(CBmainboard);
1.1 root 272:
1.1.1.3 ! root 273: switch (cbmb) {
! 274: case KONTRON_986LCD_M:
! 275: kontron_155f(regs);
! 276: return;
! 277: case RODA_RK886EX:
! 278: roda_155f(regs);
! 279: return;
! 280: case GETAC_P470:
! 281: getac_155f(regs);
! 282: return;
! 283: case MAINBOARD_DEFAULT:
! 284: bdf = GET_GLOBAL(VGAbdf);
! 285: if (bdf < 0)
! 286: goto fail;
! 287:
! 288: u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
! 289: if (vendor == PCI_VENDOR_ID_VIA) {
! 290: via_155f(regs);
! 291: return;
! 292: }
1.1 root 293: }
294:
295: fail:
296: handle_155fXX(regs);
297: }
298:
299: // Setup
300: void
301: vgahook_setup(const char *vendor, const char *part)
302: {
1.1.1.3 ! root 303: int i;
! 304:
1.1 root 305: if (! CONFIG_VGAHOOKS)
306: return;
1.1.1.3 ! root 307:
1.1 root 308: CBmainboard = 0;
1.1.1.3 ! root 309: for (i=0; i<(sizeof(mainboard_list) / sizeof(mainboard_list[0])); i++) {
! 310: if (!strcmp(vendor, mainboard_list[i].vendor) &&
! 311: !strcmp(part, mainboard_list[i].device)) {
! 312: printf("Found mainboard %s %s\n", vendor, part);
! 313: CBmainboard = mainboard_list[i].type;
! 314: break;
! 315: }
! 316: }
1.1 root 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.