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

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: 
                     15: #define RET_FUNC_NOT_SUPPORTED 0x81
                     16: #define RET_BAD_VENDOR_ID      0x83
                     17: #define RET_DEVICE_NOT_FOUND   0x86
                     18: #define RET_BUFFER_TOO_SMALL   0x89
                     19: 
                     20: // installation check
                     21: static void
                     22: handle_1ab101(struct bregs *regs)
                     23: {
                     24:     // Find max bus.
                     25:     int bdf, max;
                     26:     foreachpci(bdf, max) {
                     27:     }
                     28: 
                     29:     regs->al = 0x01; // Flags - "Config Mechanism #1" supported.
                     30:     regs->bx = 0x0210; // PCI version 2.10
                     31:     regs->cl = pci_bdf_to_bus(max - 1);
                     32:     regs->edx = 0x20494350; // "PCI "
                     33:     // XXX - bochs bios code sets edi to point to 32bit code - but no
                     34:     // reference to this in spec.
                     35:     set_code_success(regs);
                     36: }
                     37: 
                     38: // find pci device
                     39: static void
                     40: handle_1ab102(struct bregs *regs)
                     41: {
                     42:     u32 id = (regs->cx << 16) | regs->dx;
                     43:     int count = regs->si;
                     44:     int bdf, max;
                     45:     foreachpci(bdf, max) {
                     46:         u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
                     47:         if (v != id)
                     48:             continue;
                     49:         if (count--)
                     50:             continue;
                     51:         regs->bx = bdf;
                     52:         set_code_success(regs);
                     53:         return;
                     54:     }
                     55:     set_code_invalid(regs, RET_DEVICE_NOT_FOUND);
                     56: }
                     57: 
                     58: // find class code
                     59: static void
                     60: handle_1ab103(struct bregs *regs)
                     61: {
                     62:     int count = regs->si;
                     63:     u32 classprog = regs->ecx;
                     64:     int bdf, max;
                     65:     foreachpci(bdf, max) {
                     66:         u32 v = pci_config_readl(bdf, PCI_CLASS_REVISION);
                     67:         if ((v>>8) != classprog)
                     68:             continue;
                     69:         if (count--)
                     70:             continue;
                     71:         regs->bx = bdf;
                     72:         set_code_success(regs);
                     73:         return;
                     74:     }
                     75:     set_code_invalid(regs, RET_DEVICE_NOT_FOUND);
                     76: }
                     77: 
                     78: // read configuration byte
                     79: static void
                     80: handle_1ab108(struct bregs *regs)
                     81: {
                     82:     regs->cl = pci_config_readb(regs->bx, regs->di);
                     83:     set_code_success(regs);
                     84: }
                     85: 
                     86: // read configuration word
                     87: static void
                     88: handle_1ab109(struct bregs *regs)
                     89: {
                     90:     regs->cx = pci_config_readw(regs->bx, regs->di);
                     91:     set_code_success(regs);
                     92: }
                     93: 
                     94: // read configuration dword
                     95: static void
                     96: handle_1ab10a(struct bregs *regs)
                     97: {
                     98:     regs->ecx = pci_config_readl(regs->bx, regs->di);
                     99:     set_code_success(regs);
                    100: }
                    101: 
                    102: // write configuration byte
                    103: static void
                    104: handle_1ab10b(struct bregs *regs)
                    105: {
                    106:     pci_config_writeb(regs->bx, regs->di, regs->cl);
                    107:     set_code_success(regs);
                    108: }
                    109: 
                    110: // write configuration word
                    111: static void
                    112: handle_1ab10c(struct bregs *regs)
                    113: {
                    114:     pci_config_writew(regs->bx, regs->di, regs->cx);
                    115:     set_code_success(regs);
                    116: }
                    117: 
                    118: // write configuration dword
                    119: static void
                    120: handle_1ab10d(struct bregs *regs)
                    121: {
                    122:     pci_config_writel(regs->bx, regs->di, regs->ecx);
                    123:     set_code_success(regs);
                    124: }
                    125: 
                    126: // get irq routing options
                    127: static void
                    128: handle_1ab10e(struct bregs *regs)
                    129: {
                    130:     struct pir_header *pirtable_g = (void*)(GET_GLOBAL(PirOffset) + 0);
                    131:     if (! pirtable_g) {
                    132:         set_code_invalid(regs, RET_FUNC_NOT_SUPPORTED);
                    133:         return;
                    134:     }
                    135: 
                    136:     struct param_s {
                    137:         u16 size;
                    138:         u16 buf_off;
                    139:         u16 buf_seg;
                    140:     } *param_far = (void*)(regs->di+0);
                    141: 
                    142:     // Validate and update size.
                    143:     u16 bufsize = GET_FARVAR(regs->es, param_far->size);
                    144:     u16 pirsize = GET_GLOBAL(pirtable_g->size) - sizeof(struct pir_header);
                    145:     SET_FARVAR(regs->es, param_far->size, pirsize);
                    146:     if (bufsize < pirsize) {
                    147:         set_code_invalid(regs, RET_BUFFER_TOO_SMALL);
                    148:         return;
                    149:     }
                    150: 
                    151:     // Get dest buffer.
                    152:     void *buf_far = (void*)(GET_FARVAR(regs->es, param_far->buf_off)+0);
                    153:     u16 buf_seg = GET_FARVAR(regs->es, param_far->buf_seg);
                    154: 
                    155:     // Memcpy pir table slots to dest buffer.
                    156:     memcpy_far(buf_seg, buf_far
                    157:                , get_global_seg(), pirtable_g->slots
                    158:                , pirsize);
                    159: 
                    160:     // XXX - bochs bios sets bx to (1 << 9) | (1 << 11)
                    161:     regs->bx = GET_GLOBAL(pirtable_g->exclusive_irqs);
                    162:     set_code_success(regs);
                    163: }
                    164: 
                    165: static void
                    166: handle_1ab1XX(struct bregs *regs)
                    167: {
                    168:     set_code_unimplemented(regs, RET_FUNC_NOT_SUPPORTED);
                    169: }
                    170: 
                    171: void
                    172: handle_1ab1(struct bregs *regs)
                    173: {
                    174:     //debug_stub(regs);
                    175: 
                    176:     if (! CONFIG_PCIBIOS) {
                    177:         set_invalid(regs);
                    178:         return;
                    179:     }
                    180: 
                    181:     switch (regs->al) {
                    182:     case 0x01: handle_1ab101(regs); break;
                    183:     case 0x02: handle_1ab102(regs); break;
                    184:     case 0x03: handle_1ab103(regs); break;
                    185:     case 0x08: handle_1ab108(regs); break;
                    186:     case 0x09: handle_1ab109(regs); break;
                    187:     case 0x0a: handle_1ab10a(regs); break;
                    188:     case 0x0b: handle_1ab10b(regs); break;
                    189:     case 0x0c: handle_1ab10c(regs); break;
                    190:     case 0x0d: handle_1ab10d(regs); break;
                    191:     case 0x0e: handle_1ab10e(regs); break;
                    192:     default:   handle_1ab1XX(regs); break;
                    193:     }
                    194: }

unix.superglobalmegacorp.com

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