|
|
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.