Annotation of qemu/hw/pci.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * QEMU PCI bus manager
                      3:  *
                      4:  * Copyright (c) 2004 Fabrice Bellard
                      5:  * 
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: #include "vl.h"
                     25: 
                     26: //#define DEBUG_PCI
                     27: 
                     28: struct PCIBus {
                     29:     int bus_num;
                     30:     int devfn_min;
1.1.1.4 ! root       31:     pci_set_irq_fn set_irq;
1.1       root       32:     uint32_t config_reg; /* XXX: suppress */
                     33:     /* low level pic */
                     34:     SetIRQFunc *low_set_irq;
                     35:     void *irq_opaque;
                     36:     PCIDevice *devices[256];
                     37: };
                     38: 
                     39: target_phys_addr_t pci_mem_base;
                     40: static int pci_irq_index;
                     41: static PCIBus *first_bus;
                     42: 
1.1.1.4 ! root       43: PCIBus *pci_register_bus(pci_set_irq_fn set_irq, void *pic, int devfn_min)
1.1       root       44: {
                     45:     PCIBus *bus;
                     46:     bus = qemu_mallocz(sizeof(PCIBus));
1.1.1.4 ! root       47:     bus->set_irq = set_irq;
        !            48:     bus->irq_opaque = pic;
        !            49:     bus->devfn_min = devfn_min;
1.1       root       50:     first_bus = bus;
                     51:     return bus;
                     52: }
                     53: 
1.1.1.4 ! root       54: int pci_bus_num(PCIBus *s)
        !            55: {
        !            56:     return s->bus_num;
        !            57: }
        !            58: 
1.1       root       59: void generic_pci_save(QEMUFile* f, void *opaque)
                     60: {
                     61:     PCIDevice* s=(PCIDevice*)opaque;
                     62: 
                     63:     qemu_put_buffer(f, s->config, 256);
                     64: }
                     65: 
                     66: int generic_pci_load(QEMUFile* f, void *opaque, int version_id)
                     67: {
                     68:     PCIDevice* s=(PCIDevice*)opaque;
                     69: 
                     70:     if (version_id != 1)
                     71:         return -EINVAL;
                     72: 
                     73:     qemu_get_buffer(f, s->config, 256);
                     74:     return 0;
                     75: }
                     76: 
                     77: /* -1 for devfn means auto assign */
                     78: PCIDevice *pci_register_device(PCIBus *bus, const char *name, 
                     79:                                int instance_size, int devfn,
                     80:                                PCIConfigReadFunc *config_read, 
                     81:                                PCIConfigWriteFunc *config_write)
                     82: {
                     83:     PCIDevice *pci_dev;
                     84: 
                     85:     if (pci_irq_index >= PCI_DEVICES_MAX)
                     86:         return NULL;
                     87:     
                     88:     if (devfn < 0) {
                     89:         for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
                     90:             if (!bus->devices[devfn])
                     91:                 goto found;
                     92:         }
                     93:         return NULL;
                     94:     found: ;
                     95:     }
                     96:     pci_dev = qemu_mallocz(instance_size);
                     97:     if (!pci_dev)
                     98:         return NULL;
                     99:     pci_dev->bus = bus;
                    100:     pci_dev->devfn = devfn;
                    101:     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
                    102: 
                    103:     if (!config_read)
                    104:         config_read = pci_default_read_config;
                    105:     if (!config_write)
                    106:         config_write = pci_default_write_config;
                    107:     pci_dev->config_read = config_read;
                    108:     pci_dev->config_write = config_write;
                    109:     pci_dev->irq_index = pci_irq_index++;
                    110:     bus->devices[devfn] = pci_dev;
                    111:     return pci_dev;
                    112: }
                    113: 
                    114: void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
                    115:                             uint32_t size, int type, 
                    116:                             PCIMapIORegionFunc *map_func)
                    117: {
                    118:     PCIIORegion *r;
1.1.1.3   root      119:     uint32_t addr;
1.1       root      120: 
                    121:     if ((unsigned int)region_num >= PCI_NUM_REGIONS)
                    122:         return;
                    123:     r = &pci_dev->io_regions[region_num];
                    124:     r->addr = -1;
                    125:     r->size = size;
                    126:     r->type = type;
                    127:     r->map_func = map_func;
1.1.1.3   root      128:     if (region_num == PCI_ROM_SLOT) {
                    129:         addr = 0x30;
                    130:     } else {
                    131:         addr = 0x10 + region_num * 4;
                    132:     }
                    133:     *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
1.1       root      134: }
                    135: 
1.1.1.4 ! root      136: target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
1.1       root      137: {
1.1.1.4 ! root      138:     return addr + pci_mem_base;
1.1       root      139: }
                    140: 
                    141: static void pci_update_mappings(PCIDevice *d)
                    142: {
                    143:     PCIIORegion *r;
                    144:     int cmd, i;
                    145:     uint32_t last_addr, new_addr, config_ofs;
                    146:     
                    147:     cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
                    148:     for(i = 0; i < PCI_NUM_REGIONS; i++) {
                    149:         r = &d->io_regions[i];
                    150:         if (i == PCI_ROM_SLOT) {
                    151:             config_ofs = 0x30;
                    152:         } else {
                    153:             config_ofs = 0x10 + i * 4;
                    154:         }
                    155:         if (r->size != 0) {
                    156:             if (r->type & PCI_ADDRESS_SPACE_IO) {
                    157:                 if (cmd & PCI_COMMAND_IO) {
                    158:                     new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
                    159:                                                          config_ofs));
                    160:                     new_addr = new_addr & ~(r->size - 1);
                    161:                     last_addr = new_addr + r->size - 1;
                    162:                     /* NOTE: we have only 64K ioports on PC */
                    163:                     if (last_addr <= new_addr || new_addr == 0 ||
                    164:                         last_addr >= 0x10000) {
                    165:                         new_addr = -1;
                    166:                     }
                    167:                 } else {
                    168:                     new_addr = -1;
                    169:                 }
                    170:             } else {
                    171:                 if (cmd & PCI_COMMAND_MEMORY) {
                    172:                     new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
                    173:                                                          config_ofs));
                    174:                     /* the ROM slot has a specific enable bit */
                    175:                     if (i == PCI_ROM_SLOT && !(new_addr & 1))
                    176:                         goto no_mem_map;
                    177:                     new_addr = new_addr & ~(r->size - 1);
                    178:                     last_addr = new_addr + r->size - 1;
                    179:                     /* NOTE: we do not support wrapping */
                    180:                     /* XXX: as we cannot support really dynamic
                    181:                        mappings, we handle specific values as invalid
                    182:                        mappings. */
                    183:                     if (last_addr <= new_addr || new_addr == 0 ||
                    184:                         last_addr == -1) {
                    185:                         new_addr = -1;
                    186:                     }
                    187:                 } else {
                    188:                 no_mem_map:
                    189:                     new_addr = -1;
                    190:                 }
                    191:             }
                    192:             /* now do the real mapping */
                    193:             if (new_addr != r->addr) {
                    194:                 if (r->addr != -1) {
                    195:                     if (r->type & PCI_ADDRESS_SPACE_IO) {
                    196:                         int class;
                    197:                         /* NOTE: specific hack for IDE in PC case:
                    198:                            only one byte must be mapped. */
                    199:                         class = d->config[0x0a] | (d->config[0x0b] << 8);
                    200:                         if (class == 0x0101 && r->size == 4) {
                    201:                             isa_unassign_ioport(r->addr + 2, 1);
                    202:                         } else {
                    203:                             isa_unassign_ioport(r->addr, r->size);
                    204:                         }
                    205:                     } else {
1.1.1.4 ! root      206:                         cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
1.1       root      207:                                                      r->size, 
                    208:                                                      IO_MEM_UNASSIGNED);
                    209:                     }
                    210:                 }
                    211:                 r->addr = new_addr;
                    212:                 if (r->addr != -1) {
                    213:                     r->map_func(d, i, r->addr, r->size, r->type);
                    214:                 }
                    215:             }
                    216:         }
                    217:     }
                    218: }
                    219: 
                    220: uint32_t pci_default_read_config(PCIDevice *d, 
                    221:                                  uint32_t address, int len)
                    222: {
                    223:     uint32_t val;
                    224:     switch(len) {
                    225:     case 1:
                    226:         val = d->config[address];
                    227:         break;
                    228:     case 2:
                    229:         val = le16_to_cpu(*(uint16_t *)(d->config + address));
                    230:         break;
                    231:     default:
                    232:     case 4:
                    233:         val = le32_to_cpu(*(uint32_t *)(d->config + address));
                    234:         break;
                    235:     }
                    236:     return val;
                    237: }
                    238: 
                    239: void pci_default_write_config(PCIDevice *d, 
                    240:                               uint32_t address, uint32_t val, int len)
                    241: {
                    242:     int can_write, i;
                    243:     uint32_t end, addr;
                    244: 
                    245:     if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || 
                    246:                      (address >= 0x30 && address < 0x34))) {
                    247:         PCIIORegion *r;
                    248:         int reg;
                    249: 
                    250:         if ( address >= 0x30 ) {
                    251:             reg = PCI_ROM_SLOT;
                    252:         }else{
                    253:             reg = (address - 0x10) >> 2;
                    254:         }
                    255:         r = &d->io_regions[reg];
                    256:         if (r->size == 0)
                    257:             goto default_config;
                    258:         /* compute the stored value */
                    259:         if (reg == PCI_ROM_SLOT) {
                    260:             /* keep ROM enable bit */
                    261:             val &= (~(r->size - 1)) | 1;
                    262:         } else {
                    263:             val &= ~(r->size - 1);
                    264:             val |= r->type;
                    265:         }
                    266:         *(uint32_t *)(d->config + address) = cpu_to_le32(val);
                    267:         pci_update_mappings(d);
                    268:         return;
                    269:     }
                    270:  default_config:
                    271:     /* not efficient, but simple */
                    272:     addr = address;
                    273:     for(i = 0; i < len; i++) {
                    274:         /* default read/write accesses */
                    275:         switch(d->config[0x0e]) {
                    276:         case 0x00:
                    277:         case 0x80:
                    278:             switch(addr) {
                    279:             case 0x00:
                    280:             case 0x01:
                    281:             case 0x02:
                    282:             case 0x03:
                    283:             case 0x08:
                    284:             case 0x09:
                    285:             case 0x0a:
                    286:             case 0x0b:
                    287:             case 0x0e:
                    288:             case 0x10 ... 0x27: /* base */
                    289:             case 0x30 ... 0x33: /* rom */
                    290:             case 0x3d:
                    291:                 can_write = 0;
                    292:                 break;
                    293:             default:
                    294:                 can_write = 1;
                    295:                 break;
                    296:             }
                    297:             break;
                    298:         default:
                    299:         case 0x01:
                    300:             switch(addr) {
                    301:             case 0x00:
                    302:             case 0x01:
                    303:             case 0x02:
                    304:             case 0x03:
                    305:             case 0x08:
                    306:             case 0x09:
                    307:             case 0x0a:
                    308:             case 0x0b:
                    309:             case 0x0e:
                    310:             case 0x38 ... 0x3b: /* rom */
                    311:             case 0x3d:
                    312:                 can_write = 0;
                    313:                 break;
                    314:             default:
                    315:                 can_write = 1;
                    316:                 break;
                    317:             }
                    318:             break;
                    319:         }
                    320:         if (can_write) {
                    321:             d->config[addr] = val;
                    322:         }
                    323:         addr++;
                    324:         val >>= 8;
                    325:     }
                    326: 
                    327:     end = address + len;
                    328:     if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
                    329:         /* if the command register is modified, we must modify the mappings */
                    330:         pci_update_mappings(d);
                    331:     }
                    332: }
                    333: 
1.1.1.4 ! root      334: void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
1.1       root      335: {
                    336:     PCIBus *s = opaque;
                    337:     PCIDevice *pci_dev;
                    338:     int config_addr, bus_num;
                    339:     
                    340: #if defined(DEBUG_PCI) && 0
                    341:     printf("pci_data_write: addr=%08x val=%08x len=%d\n",
1.1.1.4 ! root      342:            addr, val, len);
1.1       root      343: #endif
1.1.1.4 ! root      344:     bus_num = (addr >> 16) & 0xff;
1.1       root      345:     if (bus_num != 0)
                    346:         return;
1.1.1.4 ! root      347:     pci_dev = s->devices[(addr >> 8) & 0xff];
1.1       root      348:     if (!pci_dev)
                    349:         return;
1.1.1.4 ! root      350:     config_addr = addr & 0xff;
1.1       root      351: #if defined(DEBUG_PCI)
                    352:     printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
                    353:            pci_dev->name, config_addr, val, len);
                    354: #endif
                    355:     pci_dev->config_write(pci_dev, config_addr, val, len);
                    356: }
                    357: 
1.1.1.4 ! root      358: uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
1.1       root      359: {
                    360:     PCIBus *s = opaque;
                    361:     PCIDevice *pci_dev;
                    362:     int config_addr, bus_num;
                    363:     uint32_t val;
                    364: 
1.1.1.4 ! root      365:     bus_num = (addr >> 16) & 0xff;
1.1       root      366:     if (bus_num != 0)
                    367:         goto fail;
1.1.1.4 ! root      368:     pci_dev = s->devices[(addr >> 8) & 0xff];
1.1       root      369:     if (!pci_dev) {
                    370:     fail:
                    371:         switch(len) {
                    372:         case 1:
                    373:             val = 0xff;
                    374:             break;
                    375:         case 2:
                    376:             val = 0xffff;
                    377:             break;
                    378:         default:
                    379:         case 4:
                    380:             val = 0xffffffff;
                    381:             break;
                    382:         }
                    383:         goto the_end;
                    384:     }
1.1.1.4 ! root      385:     config_addr = addr & 0xff;
1.1       root      386:     val = pci_dev->config_read(pci_dev, config_addr, len);
                    387: #if defined(DEBUG_PCI)
                    388:     printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
                    389:            pci_dev->name, config_addr, val, len);
                    390: #endif
                    391:  the_end:
                    392: #if defined(DEBUG_PCI) && 0
                    393:     printf("pci_data_read: addr=%08x val=%08x len=%d\n",
1.1.1.4 ! root      394:            addr, val, len);
1.1       root      395: #endif
                    396:     return val;
                    397: }
                    398: 
1.1.1.4 ! root      399: /***********************************************************/
        !           400: /* generic PCI irq support */
1.1       root      401: 
1.1.1.4 ! root      402: /* 0 <= irq_num <= 3. level must be 0 or 1 */
        !           403: void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
1.1       root      404: {
1.1.1.4 ! root      405:     PCIBus *bus = pci_dev->bus;
        !           406:     bus->set_irq(pci_dev, bus->irq_opaque, irq_num, level);
1.1       root      407: }
                    408: 
1.1.1.4 ! root      409: /***********************************************************/
        !           410: /* monitor info on PCI */
1.1       root      411: 
1.1.1.4 ! root      412: typedef struct {
        !           413:     uint16_t class;
        !           414:     const char *desc;
        !           415: } pci_class_desc;
        !           416: 
        !           417: static pci_class_desc pci_class_descriptions[] = 
        !           418: {
        !           419:     { 0x0101, "IDE controller"},
        !           420:     { 0x0200, "Ethernet controller"},
        !           421:     { 0x0300, "VGA controller"},
        !           422:     { 0x0600, "Host bridge"},
        !           423:     { 0x0601, "ISA bridge"},
        !           424:     { 0x0604, "PCI bridge"},
        !           425:     { 0x0c03, "USB controller"},
        !           426:     { 0, NULL}
        !           427: };
1.1       root      428: 
1.1.1.4 ! root      429: static void pci_info_device(PCIDevice *d)
1.1       root      430: {
1.1.1.4 ! root      431:     int i, class;
        !           432:     PCIIORegion *r;
        !           433:     pci_class_desc *desc;
1.1       root      434: 
1.1.1.4 ! root      435:     term_printf("  Bus %2d, device %3d, function %d:\n",
        !           436:            d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
        !           437:     class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
        !           438:     term_printf("    ");
        !           439:     desc = pci_class_descriptions;
        !           440:     while (desc->desc && class != desc->class)
        !           441:         desc++;
        !           442:     if (desc->desc) {
        !           443:         term_printf("%s", desc->desc);
        !           444:     } else {
        !           445:         term_printf("Class %04x", class);
1.1       root      446:     }
1.1.1.4 ! root      447:     term_printf(": PCI device %04x:%04x\n",
        !           448:            le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
        !           449:            le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
1.1       root      450: 
1.1.1.4 ! root      451:     if (d->config[PCI_INTERRUPT_PIN] != 0) {
        !           452:         term_printf("      IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
1.1       root      453:     }
1.1.1.4 ! root      454:     for(i = 0;i < PCI_NUM_REGIONS; i++) {
        !           455:         r = &d->io_regions[i];
        !           456:         if (r->size != 0) {
        !           457:             term_printf("      BAR%d: ", i);
        !           458:             if (r->type & PCI_ADDRESS_SPACE_IO) {
        !           459:                 term_printf("I/O at 0x%04x [0x%04x].\n", 
        !           460:                        r->addr, r->addr + r->size - 1);
        !           461:             } else {
        !           462:                 term_printf("32 bit memory at 0x%08x [0x%08x].\n", 
        !           463:                        r->addr, r->addr + r->size - 1);
        !           464:             }
        !           465:         }
1.1       root      466:     }
                    467: }
                    468: 
1.1.1.4 ! root      469: void pci_for_each_device(void (*fn)(PCIDevice *d))
1.1       root      470: {
1.1.1.4 ! root      471:     PCIBus *bus = first_bus;
1.1       root      472:     PCIDevice *d;
1.1.1.4 ! root      473:     int devfn;
1.1       root      474:     
1.1.1.4 ! root      475:     if (bus) {
        !           476:         for(devfn = 0; devfn < 256; devfn++) {
        !           477:             d = bus->devices[devfn];
        !           478:             if (d)
        !           479:                 fn(d);
        !           480:         }
1.1       root      481:     }
                    482: }
                    483: 
1.1.1.4 ! root      484: void pci_info(void)
1.1       root      485: {
1.1.1.4 ! root      486:     pci_for_each_device(pci_info_device);
1.1       root      487: }
1.1.1.3   root      488: 
                    489: /* Initialize a PCI NIC.  */
                    490: void pci_nic_init(PCIBus *bus, NICInfo *nd)
                    491: {
                    492:     if (strcmp(nd->model, "ne2k_pci") == 0) {
                    493:         pci_ne2000_init(bus, nd);
                    494:     } else if (strcmp(nd->model, "rtl8139") == 0) {
                    495:         pci_rtl8139_init(bus, nd);
1.1.1.4 ! root      496:     } else if (strcmp(nd->model, "pcnet") == 0) {
        !           497:         pci_pcnet_init(bus, nd);
1.1.1.3   root      498:     } else {
                    499:         fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
                    500:         exit (1);
                    501:     }
                    502: }
                    503: 

unix.superglobalmegacorp.com