Annotation of qemu/roms/seabios/src/pcibios.c, revision 1.1.1.2

1.1       root        1: // PCI BIOS (int 1a/b1) calls
                      2: //
                      3: // Copyright (C) 2008  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2002  MandrakeSoft S.A.
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "types.h" // u32
                      9: #include "util.h" // handle_1ab1
                     10: #include "pci.h" // pci_config_readl
                     11: #include "bregs.h" // struct bregs
                     12: #include "biosvar.h" // GET_EBDA
                     13: #include "pci_regs.h" // PCI_VENDOR_ID
                     14: 
1.1.1.2 ! root       15: // romlayout.S
        !            16: extern void bios32_entry(void);
        !            17: extern void pcibios32_entry(void);
        !            18: 
1.1       root       19: #define RET_FUNC_NOT_SUPPORTED 0x81
                     20: #define RET_BAD_VENDOR_ID      0x83
                     21: #define RET_DEVICE_NOT_FOUND   0x86
                     22: #define RET_BUFFER_TOO_SMALL   0x89
                     23: 
                     24: // installation check
                     25: static void
                     26: handle_1ab101(struct bregs *regs)
                     27: {
                     28:     // Find max bus.
                     29:     int bdf, max;
                     30:     foreachpci(bdf, max) {
                     31:     }
                     32: 
                     33:     regs->al = 0x01; // Flags - "Config Mechanism #1" supported.
                     34:     regs->bx = 0x0210; // PCI version 2.10
                     35:     regs->cl = pci_bdf_to_bus(max - 1);
                     36:     regs->edx = 0x20494350; // "PCI "
1.1.1.2 ! root       37:     regs->edi = (u32)pcibios32_entry + BUILD_BIOS_ADDR;
1.1       root       38:     set_code_success(regs);
                     39: }
                     40: 
                     41: // find pci device
                     42: static void
                     43: handle_1ab102(struct bregs *regs)
                     44: {
                     45:     u32 id = (regs->cx << 16) | regs->dx;
                     46:     int count = regs->si;
                     47:     int bdf, max;
                     48:     foreachpci(bdf, max) {
                     49:         u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
                     50:         if (v != id)
                     51:             continue;
                     52:         if (count--)
                     53:             continue;
                     54:         regs->bx = bdf;
                     55:         set_code_success(regs);
                     56:         return;
                     57:     }
                     58:     set_code_invalid(regs, RET_DEVICE_NOT_FOUND);
                     59: }
                     60: 
                     61: // find class code
                     62: static void
                     63: handle_1ab103(struct bregs *regs)
                     64: {
                     65:     int count = regs->si;
                     66:     u32 classprog = regs->ecx;
                     67:     int bdf, max;
                     68:     foreachpci(bdf, max) {
                     69:         u32 v = pci_config_readl(bdf, PCI_CLASS_REVISION);
                     70:         if ((v>>8) != classprog)
                     71:             continue;
                     72:         if (count--)
                     73:             continue;
                     74:         regs->bx = bdf;
                     75:         set_code_success(regs);
                     76:         return;
                     77:     }
                     78:     set_code_invalid(regs, RET_DEVICE_NOT_FOUND);
                     79: }
                     80: 
                     81: // read configuration byte
                     82: static void
                     83: handle_1ab108(struct bregs *regs)
                     84: {
                     85:     regs->cl = pci_config_readb(regs->bx, regs->di);
                     86:     set_code_success(regs);
                     87: }
                     88: 
                     89: // read configuration word
                     90: static void
                     91: handle_1ab109(struct bregs *regs)
                     92: {
                     93:     regs->cx = pci_config_readw(regs->bx, regs->di);
                     94:     set_code_success(regs);
                     95: }
                     96: 
                     97: // read configuration dword
                     98: static void
                     99: handle_1ab10a(struct bregs *regs)
                    100: {
                    101:     regs->ecx = pci_config_readl(regs->bx, regs->di);
                    102:     set_code_success(regs);
                    103: }
                    104: 
                    105: // write configuration byte
                    106: static void
                    107: handle_1ab10b(struct bregs *regs)
                    108: {
                    109:     pci_config_writeb(regs->bx, regs->di, regs->cl);
                    110:     set_code_success(regs);
                    111: }
                    112: 
                    113: // write configuration word
                    114: static void
                    115: handle_1ab10c(struct bregs *regs)
                    116: {
                    117:     pci_config_writew(regs->bx, regs->di, regs->cx);
                    118:     set_code_success(regs);
                    119: }
                    120: 
                    121: // write configuration dword
                    122: static void
                    123: handle_1ab10d(struct bregs *regs)
                    124: {
                    125:     pci_config_writel(regs->bx, regs->di, regs->ecx);
                    126:     set_code_success(regs);
                    127: }
                    128: 
                    129: // get irq routing options
                    130: static void
                    131: handle_1ab10e(struct bregs *regs)
                    132: {
                    133:     struct pir_header *pirtable_g = (void*)(GET_GLOBAL(PirOffset) + 0);
                    134:     if (! pirtable_g) {
                    135:         set_code_invalid(regs, RET_FUNC_NOT_SUPPORTED);
                    136:         return;
                    137:     }
                    138: 
                    139:     struct param_s {
                    140:         u16 size;
                    141:         u16 buf_off;
                    142:         u16 buf_seg;
                    143:     } *param_far = (void*)(regs->di+0);
                    144: 
                    145:     // Validate and update size.
                    146:     u16 bufsize = GET_FARVAR(regs->es, param_far->size);
                    147:     u16 pirsize = GET_GLOBAL(pirtable_g->size) - sizeof(struct pir_header);
                    148:     SET_FARVAR(regs->es, param_far->size, pirsize);
                    149:     if (bufsize < pirsize) {
                    150:         set_code_invalid(regs, RET_BUFFER_TOO_SMALL);
                    151:         return;
                    152:     }
                    153: 
                    154:     // Get dest buffer.
                    155:     void *buf_far = (void*)(GET_FARVAR(regs->es, param_far->buf_off)+0);
                    156:     u16 buf_seg = GET_FARVAR(regs->es, param_far->buf_seg);
                    157: 
                    158:     // Memcpy pir table slots to dest buffer.
                    159:     memcpy_far(buf_seg, buf_far
1.1.1.2 ! root      160:                , get_global_seg()
        !           161:                , (void*)(pirtable_g->slots) + get_global_offset()
1.1       root      162:                , pirsize);
                    163: 
                    164:     // XXX - bochs bios sets bx to (1 << 9) | (1 << 11)
                    165:     regs->bx = GET_GLOBAL(pirtable_g->exclusive_irqs);
                    166:     set_code_success(regs);
                    167: }
                    168: 
                    169: static void
                    170: handle_1ab1XX(struct bregs *regs)
                    171: {
                    172:     set_code_unimplemented(regs, RET_FUNC_NOT_SUPPORTED);
                    173: }
                    174: 
                    175: void
                    176: handle_1ab1(struct bregs *regs)
                    177: {
                    178:     //debug_stub(regs);
                    179: 
                    180:     if (! CONFIG_PCIBIOS) {
                    181:         set_invalid(regs);
                    182:         return;
                    183:     }
                    184: 
                    185:     switch (regs->al) {
                    186:     case 0x01: handle_1ab101(regs); break;
                    187:     case 0x02: handle_1ab102(regs); break;
                    188:     case 0x03: handle_1ab103(regs); break;
                    189:     case 0x08: handle_1ab108(regs); break;
                    190:     case 0x09: handle_1ab109(regs); break;
                    191:     case 0x0a: handle_1ab10a(regs); break;
                    192:     case 0x0b: handle_1ab10b(regs); break;
                    193:     case 0x0c: handle_1ab10c(regs); break;
                    194:     case 0x0d: handle_1ab10d(regs); break;
                    195:     case 0x0e: handle_1ab10e(regs); break;
                    196:     default:   handle_1ab1XX(regs); break;
                    197:     }
                    198: }
1.1.1.2 ! root      199: 
        !           200: 
        !           201: /****************************************************************
        !           202:  * 32bit interface
        !           203:  ****************************************************************/
        !           204: 
        !           205: // Entry point for 32bit pci bios functions.
        !           206: void VISIBLE32SEG
        !           207: handle_pcibios32(struct bregs *regs)
        !           208: {
        !           209:     debug_enter(regs, DEBUG_HDL_pcibios32);
        !           210:     handle_1ab1(regs);
        !           211: }
        !           212: 
        !           213: struct bios32_s {
        !           214:     u32 signature;
        !           215:     u32 entry;
        !           216:     u8 version;
        !           217:     u8 length;
        !           218:     u8 checksum;
        !           219:     u8 reserved[5];
        !           220: } PACKED;
        !           221: 
        !           222: struct bios32_s BIOS32HEADER __aligned(16) VAR16EXPORT = {
        !           223:     .signature = 0x5f32335f, // _32_
        !           224:     .length = sizeof(BIOS32HEADER) / 16,
        !           225: };
        !           226: 
        !           227: void
        !           228: bios32_setup(void)
        !           229: {
        !           230:     dprintf(3, "init bios32\n");
        !           231: 
        !           232:     BIOS32HEADER.entry = (u32)bios32_entry;
        !           233:     BIOS32HEADER.checksum -= checksum(&BIOS32HEADER, sizeof(BIOS32HEADER));
        !           234: }

unix.superglobalmegacorp.com

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