Revision a0c7a97e hw/pci.c

b/hw/pci.c
560 560
        if (!r->size || r->addr == PCI_BAR_UNMAPPED)
561 561
            continue;
562 562
        if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
563
            isa_unassign_ioport(r->addr, r->size);
563
            isa_unassign_ioport(r->addr, r->filtered_size);
564 564
        } else {
565 565
            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
566
                                                     r->size,
566
                                                     r->filtered_size,
567 567
                                                     IO_MEM_UNASSIGNED);
568 568
        }
569 569
    }
......
608 608
    r = &pci_dev->io_regions[region_num];
609 609
    r->addr = PCI_BAR_UNMAPPED;
610 610
    r->size = size;
611
    r->filtered_size = size;
611 612
    r->type = type;
612 613
    r->map_func = map_func;
613 614

  
......
628 629
    }
629 630
}
630 631

  
632
static uint32_t pci_config_get_io_base(PCIDevice *d,
633
                                       uint32_t base, uint32_t base_upper16)
634
{
635
    uint32_t val;
636

  
637
    val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
638
    if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
639
        val |= (uint32_t)pci_get_word(d->config + PCI_IO_BASE_UPPER16) << 16;
640
    }
641
    return val;
642
}
643

  
644
static uint64_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
645
{
646
    return ((uint64_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
647
        << 16;
648
}
649

  
650
static uint64_t pci_config_get_pref_base(PCIDevice *d,
651
                                         uint32_t base, uint32_t upper)
652
{
653
    uint64_t val;
654
    val = ((uint64_t)pci_get_word(d->config + base) &
655
           PCI_PREF_RANGE_MASK) << 16;
656
    val |= (uint64_t)pci_get_long(d->config + upper) << 32;
657
    return val;
658
}
659

  
660
static pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
661
{
662
    pcibus_t base;
663
    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
664
        base = pci_config_get_io_base(bridge,
665
                                      PCI_IO_BASE, PCI_IO_BASE_UPPER16);
666
    } else {
667
        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
668
            base = pci_config_get_pref_base(
669
                bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
670
        } else {
671
            base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
672
        }
673
    }
674

  
675
    return base;
676
}
677

  
678
static pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
679
{
680
    pcibus_t limit;
681
    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
682
        limit = pci_config_get_io_base(bridge,
683
                                      PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
684
        limit |= 0xfff;         /* PCI bridge spec 3.2.5.6. */
685
    } else {
686
        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
687
            limit = pci_config_get_pref_base(
688
                bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
689
        } else {
690
            limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
691
        }
692
        limit |= 0xfffff;       /* PCI bridge spec 3.2.5.{1, 8}. */
693
    }
694
    return limit;
695
}
696

  
697
static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
698
                              uint8_t type)
699
{
700
    pcibus_t base = *addr;
701
    pcibus_t limit = *addr + *size - 1;
702
    PCIDevice *br;
703

  
704
    for (br = d->bus->parent_dev; br; br = br->bus->parent_dev) {
705
        uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);
706

  
707
        if (type & PCI_BASE_ADDRESS_SPACE_IO) {
708
            if (!(cmd & PCI_COMMAND_IO)) {
709
                goto no_map;
710
            }
711
        } else {
712
            if (!(cmd & PCI_COMMAND_MEMORY)) {
713
                goto no_map;
714
            }
715
        }
716

  
717
        base = MAX(base, pci_bridge_get_base(br, type));
718
        limit = MIN(limit, pci_bridge_get_limit(br, type));
719
    }
720

  
721
    if (base > limit) {
722
    no_map:
723
        *addr = PCI_BAR_UNMAPPED;
724
        *size = 0;
725
    } else {
726
        *addr = base;
727
        *size = limit - base + 1;
728
    }
729
}
730

  
631 731
static void pci_update_mappings(PCIDevice *d)
632 732
{
633 733
    PCIIORegion *r;
634 734
    int cmd, i;
635 735
    pcibus_t last_addr, new_addr;
736
    pcibus_t filtered_size;
636 737

  
637 738
    cmd = pci_get_word(d->config + PCI_COMMAND);
638 739
    for(i = 0; i < PCI_NUM_REGIONS; i++) {
......
696 797
            }
697 798
        }
698 799

  
800
        /* bridge filtering */
801
        filtered_size = r->size;
802
        if (new_addr != PCI_BAR_UNMAPPED) {
803
            pci_bridge_filter(d, &new_addr, &filtered_size, r->type);
804
        }
805

  
699 806
        /* This bar isn't changed */
700
        if (new_addr == r->addr)
807
        if (new_addr == r->addr && filtered_size == r->filtered_size)
701 808
            continue;
702 809

  
703 810
        /* now do the real mapping */
......
710 817
                if (class == 0x0101 && r->size == 4) {
711 818
                    isa_unassign_ioport(r->addr + 2, 1);
712 819
                } else {
713
                    isa_unassign_ioport(r->addr, r->size);
820
                    isa_unassign_ioport(r->addr, r->filtered_size);
714 821
                }
715 822
            } else {
716 823
                cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
717
                                             r->size,
824
                                             r->filtered_size,
718 825
                                             IO_MEM_UNASSIGNED);
719
                qemu_unregister_coalesced_mmio(r->addr, r->size);
826
                qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
720 827
            }
721 828
        }
722 829
        r->addr = new_addr;
830
        r->filtered_size = filtered_size;
723 831
        if (r->addr != PCI_BAR_UNMAPPED) {
724
            r->map_func(d, i, r->addr, r->size, r->type);
832
            /*
833
             * TODO: currently almost all the map funcions assumes
834
             * filtered_size == size and addr & ~(size - 1) == addr.
835
             * However with bridge filtering, they aren't always true.
836
             * Teach them such cases, such that filtered_size < size and
837
             * addr & (size - 1) != 0.
838
             */
839
            r->map_func(d, i, r->addr, r->filtered_size, r->type);
725 840
        }
726 841
    }
727 842
}
......
994 1109
    uint32_t did;
995 1110
} PCIBridge;
996 1111

  
1112

  
1113
static void pci_bridge_update_mappings_fn(PCIBus *b, PCIDevice *d)
1114
{
1115
    pci_update_mappings(d);
1116
}
1117

  
1118
static void pci_bridge_update_mappings(PCIBus *b)
1119
{
1120
    PCIBus *child;
1121

  
1122
    pci_for_each_device_under_bus(b, pci_bridge_update_mappings_fn);
1123

  
1124
    QLIST_FOREACH(child, &b->child, sibling) {
1125
        pci_bridge_update_mappings(child);
1126
    }
1127
}
1128

  
997 1129
static void pci_bridge_write_config(PCIDevice *d,
998 1130
                             uint32_t address, uint32_t val, int len)
999 1131
{
1000 1132
    pci_default_write_config(d, address, val, len);
1133

  
1134
    if (/* io base/limit */
1135
        ranges_overlap(address, len, PCI_IO_BASE, 2) ||
1136

  
1137
        /* memory base/limit, prefetchable base/limit and
1138
           io base/limit upper 16 */
1139
        ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
1140
        pci_bridge_update_mappings(d->bus);
1141
    }
1001 1142
}
1002 1143

  
1003 1144
PCIBus *pci_find_bus(PCIBus *bus, int bus_num)

Also available in: Unified diff