Annotation of qemu/hw/pci_bridge.c, revision 1.1.1.3

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 dea
                      8: 
                      9:  * in the Software without restriction, including without limitation the rights
                     10:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     11:  * copies of the Software, and to permit persons to whom the Software is
                     12:  * furnished to do so, subject to the following conditions:
                     13:  *
                     14:  * The above copyright notice and this permission notice shall be included in
                     15:  * all copies or substantial portions of the Software.
                     16:  *
                     17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     18:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
                     22: 
                     23:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     24:  * THE SOFTWARE.
                     25:  */
                     26: /*
                     27:  * split out from pci.c
                     28:  * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
                     29:  *                    VA Linux Systems Japan K.K.
                     30:  */
                     31: 
                     32: #include "pci_bridge.h"
                     33: #include "pci_internals.h"
                     34: #include "range.h"
                     35: 
                     36: /* PCI bridge subsystem vendor ID helper functions */
                     37: #define PCI_SSVID_SIZEOF        8
                     38: #define PCI_SSVID_SVID          4
                     39: #define PCI_SSVID_SSID          6
                     40: 
                     41: int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset,
                     42:                           uint16_t svid, uint16_t ssid)
                     43: {
                     44:     int pos;
                     45:     pos = pci_add_capability(dev, PCI_CAP_ID_SSVID, offset, PCI_SSVID_SIZEOF);
                     46:     if (pos < 0) {
                     47:         return pos;
                     48:     }
                     49: 
                     50:     pci_set_word(dev->config + pos + PCI_SSVID_SVID, svid);
                     51:     pci_set_word(dev->config + pos + PCI_SSVID_SSID, ssid);
                     52:     return pos;
                     53: }
                     54: 
                     55: /* Accessor function to get parent bridge device from pci bus. */
                     56: PCIDevice *pci_bridge_get_device(PCIBus *bus)
                     57: {
                     58:     return bus->parent_dev;
                     59: }
                     60: 
                     61: /* Accessor function to get secondary bus from pci-to-pci bridge device */
                     62: PCIBus *pci_bridge_get_sec_bus(PCIBridge *br)
                     63: {
                     64:     return &br->sec_bus;
                     65: }
                     66: 
                     67: static uint32_t pci_config_get_io_base(const PCIDevice *d,
                     68:                                        uint32_t base, uint32_t base_upper16)
                     69: {
                     70:     uint32_t val;
                     71: 
                     72:     val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
                     73:     if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
                     74:         val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
                     75:     }
                     76:     return val;
                     77: }
                     78: 
                     79: static pcibus_t pci_config_get_memory_base(const PCIDevice *d, uint32_t base)
                     80: {
                     81:     return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
                     82:         << 16;
                     83: }
                     84: 
                     85: static pcibus_t pci_config_get_pref_base(const PCIDevice *d,
                     86:                                          uint32_t base, uint32_t upper)
                     87: {
                     88:     pcibus_t tmp;
                     89:     pcibus_t val;
                     90: 
                     91:     tmp = (pcibus_t)pci_get_word(d->config + base);
                     92:     val = (tmp & PCI_PREF_RANGE_MASK) << 16;
                     93:     if (tmp & PCI_PREF_RANGE_TYPE_64) {
                     94:         val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
                     95:     }
                     96:     return val;
                     97: }
                     98: 
                     99: /* accessor function to get bridge filtering base address */
                    100: pcibus_t pci_bridge_get_base(const PCIDevice *bridge, uint8_t type)
                    101: {
                    102:     pcibus_t base;
                    103:     if (type & PCI_BASE_ADDRESS_SPACE_IO) {
                    104:         base = pci_config_get_io_base(bridge,
                    105:                                       PCI_IO_BASE, PCI_IO_BASE_UPPER16);
                    106:     } else {
                    107:         if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                    108:             base = pci_config_get_pref_base(
                    109:                 bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
                    110:         } else {
                    111:             base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
                    112:         }
                    113:     }
                    114: 
                    115:     return base;
                    116: }
                    117: 
                    118: /* accessor funciton to get bridge filtering limit */
                    119: pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type)
                    120: {
                    121:     pcibus_t limit;
                    122:     if (type & PCI_BASE_ADDRESS_SPACE_IO) {
                    123:         limit = pci_config_get_io_base(bridge,
                    124:                                       PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
                    125:         limit |= 0xfff;         /* PCI bridge spec 3.2.5.6. */
                    126:     } else {
                    127:         if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                    128:             limit = pci_config_get_pref_base(
                    129:                 bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
                    130:         } else {
                    131:             limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
                    132:         }
                    133:         limit |= 0xfffff;       /* PCI bridge spec 3.2.5.{1, 8}. */
                    134:     }
                    135:     return limit;
                    136: }
                    137: 
1.1.1.2   root      138: static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
                    139:                                   uint8_t type, const char *name,
                    140:                                   MemoryRegion *space,
                    141:                                   MemoryRegion *parent_space,
                    142:                                   bool enabled)
                    143: {
                    144:     pcibus_t base = pci_bridge_get_base(&bridge->dev, type);
                    145:     pcibus_t limit = pci_bridge_get_limit(&bridge->dev, type);
                    146:     /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly.
                    147:      * Apparently no way to do this with existing memory APIs. */
                    148:     pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;
                    149: 
                    150:     memory_region_init_alias(alias, name, space, base, size);
                    151:     memory_region_add_subregion_overlap(parent_space, base, alias, 1);
                    152: }
                    153: 
                    154: static void pci_bridge_cleanup_alias(MemoryRegion *alias,
                    155:                                      MemoryRegion *parent_space)
                    156: {
                    157:     memory_region_del_subregion(parent_space, alias);
                    158:     memory_region_destroy(alias);
                    159: }
                    160: 
                    161: static void pci_bridge_region_init(PCIBridge *br)
                    162: {
                    163:     PCIBus *parent = br->dev.bus;
                    164:     uint16_t cmd = pci_get_word(br->dev.config + PCI_COMMAND);
                    165: 
                    166:     pci_bridge_init_alias(br, &br->alias_pref_mem,
                    167:                           PCI_BASE_ADDRESS_MEM_PREFETCH,
                    168:                           "pci_bridge_pref_mem",
                    169:                           &br->address_space_mem,
                    170:                           parent->address_space_mem,
                    171:                           cmd & PCI_COMMAND_MEMORY);
                    172:     pci_bridge_init_alias(br, &br->alias_mem,
                    173:                           PCI_BASE_ADDRESS_SPACE_MEMORY,
                    174:                           "pci_bridge_mem",
                    175:                           &br->address_space_mem,
                    176:                           parent->address_space_mem,
                    177:                           cmd & PCI_COMMAND_MEMORY);
                    178:     pci_bridge_init_alias(br, &br->alias_io,
                    179:                           PCI_BASE_ADDRESS_SPACE_IO,
                    180:                           "pci_bridge_io",
                    181:                           &br->address_space_io,
                    182:                           parent->address_space_io,
                    183:                           cmd & PCI_COMMAND_IO);
                    184:    /* TODO: optinal VGA and VGA palette snooping support. */
                    185: }
                    186: 
                    187: static void pci_bridge_region_cleanup(PCIBridge *br)
                    188: {
                    189:     PCIBus *parent = br->dev.bus;
                    190:     pci_bridge_cleanup_alias(&br->alias_io,
                    191:                              parent->address_space_io);
                    192:     pci_bridge_cleanup_alias(&br->alias_mem,
                    193:                              parent->address_space_mem);
                    194:     pci_bridge_cleanup_alias(&br->alias_pref_mem,
                    195:                              parent->address_space_mem);
                    196: }
                    197: 
                    198: static void pci_bridge_update_mappings(PCIBridge *br)
                    199: {
                    200:     /* Make updates atomic to: handle the case of one VCPU updating the bridge
                    201:      * while another accesses an unaffected region. */
                    202:     memory_region_transaction_begin();
                    203:     pci_bridge_region_cleanup(br);
                    204:     pci_bridge_region_init(br);
                    205:     memory_region_transaction_commit();
                    206: }
                    207: 
1.1       root      208: /* default write_config function for PCI-to-PCI bridge */
                    209: void pci_bridge_write_config(PCIDevice *d,
                    210:                              uint32_t address, uint32_t val, int len)
                    211: {
                    212:     PCIBridge *s = container_of(d, PCIBridge, dev);
                    213:     uint16_t oldctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
                    214:     uint16_t newctl;
                    215: 
                    216:     pci_default_write_config(d, address, val, len);
                    217: 
1.1.1.2   root      218:     if (ranges_overlap(address, len, PCI_COMMAND, 2) ||
                    219: 
                    220:         /* io base/limit */
1.1       root      221:         ranges_overlap(address, len, PCI_IO_BASE, 2) ||
                    222: 
                    223:         /* memory base/limit, prefetchable base/limit and
                    224:            io base/limit upper 16 */
                    225:         ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
1.1.1.2   root      226:         pci_bridge_update_mappings(s);
1.1       root      227:     }
                    228: 
                    229:     newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
                    230:     if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
                    231:         /* Trigger hot reset on 0->1 transition. */
                    232:         pci_bus_reset(&s->sec_bus);
                    233:     }
                    234: }
                    235: 
                    236: void pci_bridge_disable_base_limit(PCIDevice *dev)
                    237: {
                    238:     uint8_t *conf = dev->config;
                    239: 
                    240:     pci_byte_test_and_set_mask(conf + PCI_IO_BASE,
                    241:                                PCI_IO_RANGE_MASK & 0xff);
                    242:     pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
                    243:                                  PCI_IO_RANGE_MASK & 0xff);
                    244:     pci_word_test_and_set_mask(conf + PCI_MEMORY_BASE,
                    245:                                PCI_MEMORY_RANGE_MASK & 0xffff);
                    246:     pci_word_test_and_clear_mask(conf + PCI_MEMORY_LIMIT,
                    247:                                  PCI_MEMORY_RANGE_MASK & 0xffff);
                    248:     pci_word_test_and_set_mask(conf + PCI_PREF_MEMORY_BASE,
                    249:                                PCI_PREF_RANGE_MASK & 0xffff);
                    250:     pci_word_test_and_clear_mask(conf + PCI_PREF_MEMORY_LIMIT,
                    251:                                  PCI_PREF_RANGE_MASK & 0xffff);
1.1.1.3 ! root      252:     pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0);
        !           253:     pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0);
1.1       root      254: }
                    255: 
                    256: /* reset bridge specific configuration registers */
                    257: void pci_bridge_reset_reg(PCIDevice *dev)
                    258: {
                    259:     uint8_t *conf = dev->config;
                    260: 
                    261:     conf[PCI_PRIMARY_BUS] = 0;
                    262:     conf[PCI_SECONDARY_BUS] = 0;
                    263:     conf[PCI_SUBORDINATE_BUS] = 0;
                    264:     conf[PCI_SEC_LATENCY_TIMER] = 0;
                    265: 
                    266:     /*
                    267:      * the default values for base/limit registers aren't specified
                    268:      * in the PCI-to-PCI-bridge spec. So we don't thouch them here.
                    269:      * Each implementation can override it.
                    270:      * typical implementation does
                    271:      * zero base/limit registers or
                    272:      * disable forwarding: pci_bridge_disable_base_limit()
                    273:      * If disable forwarding is wanted, call pci_bridge_disable_base_limit()
                    274:      * after this function.
                    275:      */
                    276:     pci_byte_test_and_clear_mask(conf + PCI_IO_BASE,
                    277:                                  PCI_IO_RANGE_MASK & 0xff);
                    278:     pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
                    279:                                  PCI_IO_RANGE_MASK & 0xff);
                    280:     pci_word_test_and_clear_mask(conf + PCI_MEMORY_BASE,
                    281:                                  PCI_MEMORY_RANGE_MASK & 0xffff);
                    282:     pci_word_test_and_clear_mask(conf + PCI_MEMORY_LIMIT,
                    283:                                  PCI_MEMORY_RANGE_MASK & 0xffff);
                    284:     pci_word_test_and_clear_mask(conf + PCI_PREF_MEMORY_BASE,
                    285:                                  PCI_PREF_RANGE_MASK & 0xffff);
                    286:     pci_word_test_and_clear_mask(conf + PCI_PREF_MEMORY_LIMIT,
                    287:                                  PCI_PREF_RANGE_MASK & 0xffff);
1.1.1.3 ! root      288:     pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0);
        !           289:     pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0);
1.1       root      290: 
                    291:     pci_set_word(conf + PCI_BRIDGE_CONTROL, 0);
                    292: }
                    293: 
                    294: /* default reset function for PCI-to-PCI bridge */
                    295: void pci_bridge_reset(DeviceState *qdev)
                    296: {
1.1.1.3 ! root      297:     PCIDevice *dev = PCI_DEVICE(qdev);
1.1       root      298:     pci_bridge_reset_reg(dev);
                    299: }
                    300: 
                    301: /* default qdev initialization function for PCI-to-PCI bridge */
                    302: int pci_bridge_initfn(PCIDevice *dev)
                    303: {
                    304:     PCIBus *parent = dev->bus;
                    305:     PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
                    306:     PCIBus *sec_bus = &br->sec_bus;
                    307: 
1.1.1.3 ! root      308:     pci_word_test_and_set_mask(dev->config + PCI_STATUS,
        !           309:                                PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
1.1       root      310:     pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
                    311:     dev->config[PCI_HEADER_TYPE] =
                    312:         (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
                    313:         PCI_HEADER_TYPE_BRIDGE;
                    314:     pci_set_word(dev->config + PCI_SEC_STATUS,
                    315:                  PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
                    316: 
1.1.1.3 ! root      317:     /*
        !           318:      * If we don't specify the name, the bus will be addressed as <id>.0, where
        !           319:      * id is the device id.
        !           320:      * Since PCI Bridge devices have a single bus each, we don't need the index:
        !           321:      * let users address the bus using the device name.
        !           322:      */
        !           323:     if (!br->bus_name && dev->qdev.id && *dev->qdev.id) {
        !           324:            br->bus_name = dev->qdev.id;
        !           325:     }
        !           326: 
1.1       root      327:     qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev,
                    328:                         br->bus_name);
                    329:     sec_bus->parent_dev = dev;
                    330:     sec_bus->map_irq = br->map_irq;
1.1.1.2   root      331:     sec_bus->address_space_mem = &br->address_space_mem;
                    332:     memory_region_init(&br->address_space_mem, "pci_bridge_pci", INT64_MAX);
                    333:     sec_bus->address_space_io = &br->address_space_io;
                    334:     memory_region_init(&br->address_space_io, "pci_bridge_io", 65536);
                    335:     pci_bridge_region_init(br);
1.1       root      336:     QLIST_INIT(&sec_bus->child);
                    337:     QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);
                    338:     return 0;
                    339: }
                    340: 
                    341: /* default qdev clean up function for PCI-to-PCI bridge */
                    342: int pci_bridge_exitfn(PCIDevice *pci_dev)
                    343: {
                    344:     PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
                    345:     assert(QLIST_EMPTY(&s->sec_bus.child));
                    346:     QLIST_REMOVE(&s->sec_bus, sibling);
1.1.1.2   root      347:     pci_bridge_region_cleanup(s);
                    348:     memory_region_destroy(&s->address_space_mem);
                    349:     memory_region_destroy(&s->address_space_io);
1.1       root      350:     /* qbus_free() is called automatically by qdev_free() */
                    351:     return 0;
                    352: }
                    353: 
                    354: /*
                    355:  * before qdev initialization(qdev_init()), this function sets bus_name and
                    356:  * map_irq callback which are necessry for pci_bridge_initfn() to
                    357:  * initialize bus.
                    358:  */
                    359: void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
                    360:                         pci_map_irq_fn map_irq)
                    361: {
                    362:     br->map_irq = map_irq;
                    363:     br->bus_name = bus_name;
                    364: }

unix.superglobalmegacorp.com

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