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

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: }

unix.superglobalmegacorp.com

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