Annotation of qemu/roms/seabios/src/vgahooks.c, revision 1.1.1.4

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.
1.1.1.4 ! root       16: int VGAbdf VAR16VISIBLE = -1;
1.1       root       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: 
                    308:     for (i=0; i<(sizeof(mainboard_list) / sizeof(mainboard_list[0])); i++) {
                    309:         if (!strcmp(vendor, mainboard_list[i].vendor) &&
                    310:             !strcmp(part, mainboard_list[i].device)) {
1.1.1.4 ! root      311:             printf("Found mainboard %s %s\n", vendor, part);
1.1.1.3   root      312:             CBmainboard = mainboard_list[i].type;
                    313:             break;
                    314:         }
                    315:     }
1.1       root      316: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.