Lines Matching +full:rcu +full:- +full:big +full:- +full:endian +full:- +full:mask

4  * Copyright (c) 2014-2020, IBM Corporation.
7 * COPYING file in the top-level directory.
13 #include "hw/pci-host/pnv_phb3_regs.h"
14 #include "hw/pci-host/pnv_phb.h"
15 #include "hw/pci-host/pnv_phb3.h"
21 #include "hw/qdev-properties.h"
27 (phb)->chip_id, (phb)->phb_id, ## __VA_ARGS__)
31 PCIHostState *pci = PCI_HOST_BRIDGE(phb->phb_base); in pnv_phb3_find_cfg_dev()
32 uint64_t addr = phb->regs[PHB_CONFIG_ADDRESS >> 3]; in pnv_phb3_find_cfg_dev()
41 return pci_find_device(pci->bus, bus, devfn); in pnv_phb3_find_cfg_dev()
45 * The CONFIG_DATA register expects little endian accesses, but as the
46 * region is big endian, we have to swap the value.
58 cfg_addr = (phb->regs[PHB_CONFIG_ADDRESS >> 3] >> 32) & 0xffc; in pnv_phb3_config_write()
63 * conventional pci device can be behind pcie-to-pci bridge. in pnv_phb3_config_write()
94 cfg_addr = (phb->regs[PHB_CONFIG_ADDRESS >> 3] >> 32) & 0xffc; in pnv_phb3_config_read()
99 * conventional pci device can be behind pcie-to-pci bridge. in pnv_phb3_config_read()
121 PnvPBCQState *pbcq = &phb->pbcq; in pnv_phb3_check_m32()
123 if (memory_region_is_mapped(&phb->mr_m32)) { in pnv_phb3_check_m32()
124 memory_region_del_subregion(phb->mr_m32.container, &phb->mr_m32); in pnv_phb3_check_m32()
127 if (!(phb->regs[PHB_PHB3_CONFIG >> 3] & PHB_PHB3C_M32_EN)) { in pnv_phb3_check_m32()
132 base = phb->regs[PHB_M32_BASE_ADDR >> 3]; in pnv_phb3_check_m32()
133 start = phb->regs[PHB_M32_START_ADDR >> 3]; in pnv_phb3_check_m32()
134 size = ~(phb->regs[PHB_M32_BASE_MASK >> 3] | 0xfffc000000000000ull) + 1; in pnv_phb3_check_m32()
137 if (memory_region_is_mapped(&pbcq->mmbar0) && in pnv_phb3_check_m32()
138 base >= pbcq->mmio0_base && in pnv_phb3_check_m32()
139 (base + size) <= (pbcq->mmio0_base + pbcq->mmio0_size)) { in pnv_phb3_check_m32()
140 parent = &pbcq->mmbar0; in pnv_phb3_check_m32()
141 base -= pbcq->mmio0_base; in pnv_phb3_check_m32()
142 } else if (memory_region_is_mapped(&pbcq->mmbar1) && in pnv_phb3_check_m32()
143 base >= pbcq->mmio1_base && in pnv_phb3_check_m32()
144 (base + size) <= (pbcq->mmio1_base + pbcq->mmio1_size)) { in pnv_phb3_check_m32()
145 parent = &pbcq->mmbar1; in pnv_phb3_check_m32()
146 base -= pbcq->mmio1_base; in pnv_phb3_check_m32()
152 memory_region_init_alias(&phb->mr_m32, OBJECT(phb), "phb3-m32", in pnv_phb3_check_m32()
153 &phb->pci_mmio, start, size); in pnv_phb3_check_m32()
154 memory_region_add_subregion(parent, base, &phb->mr_m32); in pnv_phb3_check_m32()
161 PnvPBCQState *pbcq = &phb->pbcq; in pnv_phb3_check_m64()
163 if (memory_region_is_mapped(&phb->mr_m64[index])) { in pnv_phb3_check_m64()
164 /* Should we destroy it in RCU friendly way... ? */ in pnv_phb3_check_m64()
165 memory_region_del_subregion(phb->mr_m64[index].container, in pnv_phb3_check_m64()
166 &phb->mr_m64[index]); in pnv_phb3_check_m64()
170 m64 = phb->ioda_M64BT[index]; in pnv_phb3_check_m64()
184 start = base | (phb->regs[PHB_M64_UPPER_BITS >> 3]); in pnv_phb3_check_m64()
187 if (memory_region_is_mapped(&pbcq->mmbar0) && in pnv_phb3_check_m64()
188 base >= pbcq->mmio0_base && in pnv_phb3_check_m64()
189 (base + size) <= (pbcq->mmio0_base + pbcq->mmio0_size)) { in pnv_phb3_check_m64()
190 parent = &pbcq->mmbar0; in pnv_phb3_check_m64()
191 base -= pbcq->mmio0_base; in pnv_phb3_check_m64()
192 } else if (memory_region_is_mapped(&pbcq->mmbar1) && in pnv_phb3_check_m64()
193 base >= pbcq->mmio1_base && in pnv_phb3_check_m64()
194 (base + size) <= (pbcq->mmio1_base + pbcq->mmio1_size)) { in pnv_phb3_check_m64()
195 parent = &pbcq->mmbar1; in pnv_phb3_check_m64()
196 base -= pbcq->mmio1_base; in pnv_phb3_check_m64()
202 memory_region_init_alias(&phb->mr_m64[index], OBJECT(phb), "phb3-m64", in pnv_phb3_check_m64()
203 &phb->pci_mmio, start, size); in pnv_phb3_check_m64()
204 memory_region_add_subregion(parent, base, &phb->mr_m64[index]); in pnv_phb3_check_m64()
220 phb->ioda_LXIVT[idx] = val & (IODA2_LXIVT_SERVER | in pnv_phb3_lxivt_write()
232 ics_write_xive(&phb->lsis, idx, server, prio, prio); in pnv_phb3_lxivt_write()
238 uint64_t adreg = phb->regs[PHB_IODA_ADDR >> 3]; in pnv_phb3_ioda_access()
241 unsigned int mask; in pnv_phb3_ioda_access() local
246 tptr = phb->ioda_LIST; in pnv_phb3_ioda_access()
247 mask = 7; in pnv_phb3_ioda_access()
250 tptr = phb->ioda_LXIVT; in pnv_phb3_ioda_access()
251 mask = 7; in pnv_phb3_ioda_access()
255 mask = 31; in pnv_phb3_ioda_access()
258 mask = 63; in pnv_phb3_ioda_access()
261 mask = 7; in pnv_phb3_ioda_access()
265 mask = 255; in pnv_phb3_ioda_access()
268 tptr = phb->ioda_TVT; in pnv_phb3_ioda_access()
269 mask = 511; in pnv_phb3_ioda_access()
273 mask = 63; in pnv_phb3_ioda_access()
276 tptr = phb->ioda_M64BT; in pnv_phb3_ioda_access()
277 mask = 15; in pnv_phb3_ioda_access()
280 tptr = phb->ioda_MDT; in pnv_phb3_ioda_access()
281 mask = 255; in pnv_phb3_ioda_access()
284 tptr = phb->ioda_PEEV; in pnv_phb3_ioda_access()
285 mask = 3; in pnv_phb3_ioda_access()
291 index &= mask; in pnv_phb3_ioda_access()
302 index = (index + 1) & mask; in pnv_phb3_ioda_access()
305 phb->regs[PHB_IODA_ADDR >> 3] = adreg; in pnv_phb3_ioda_access()
352 ICSState *ics = &phb->lsis; in pnv_phb3_remap_irqs()
353 uint32_t local, global, count, mask, comp; in pnv_phb3_remap_irqs() local
355 PnvPBCQState *pbcq = &phb->pbcq; in pnv_phb3_remap_irqs()
361 baren = pbcq->nest_regs[PBCQ_NEST_BAR_EN]; in pnv_phb3_remap_irqs()
364 ics->offset = 0; in pnv_phb3_remap_irqs()
369 local = GETFIELD(PHB_LSI_SRC_ID, phb->regs[PHB_LSI_SOURCE_ID >> 3]) << 3; in pnv_phb3_remap_irqs()
373 pbcq->nest_regs[PBCQ_NEST_LSI_SRC_ID]) << 3; in pnv_phb3_remap_irqs()
379 ics->offset = 0; in pnv_phb3_remap_irqs()
385 pbcq->nest_regs[PBCQ_NEST_IRSN_COMPARE]); in pnv_phb3_remap_irqs()
386 mask = GETFIELD(PBCQ_NEST_IRSN_COMP, in pnv_phb3_remap_irqs()
387 pbcq->nest_regs[PBCQ_NEST_IRSN_MASK]); in pnv_phb3_remap_irqs()
388 count = ((~mask) + 1) & 0x7ffff; in pnv_phb3_remap_irqs()
389 phb->total_irq = count; in pnv_phb3_remap_irqs()
401 if ((comp & mask) != comp) { in pnv_phb3_remap_irqs()
402 phb3_error(phb, "IRQ compare bits not in mask: comp=0x%x mask=0x%x", in pnv_phb3_remap_irqs()
403 comp, mask); in pnv_phb3_remap_irqs()
404 comp &= mask; in pnv_phb3_remap_irqs()
407 ics->offset = comp + global; in pnv_phb3_remap_irqs()
410 pnv_phb3_msi_update_config(&phb->msis, comp, count - PNV_PHB3_NUM_LSI); in pnv_phb3_remap_irqs()
417 phb->regs[PHB_LSI_SOURCE_ID >> 3] = val; in pnv_phb3_lsi_src_id_write()
426 QLIST_FOREACH(ds, &phb->dma_spaces, list) { in pnv_phb3_rtc_invalidate()
427 ds->pe_num = PHB_INVALID_PE; in pnv_phb3_rtc_invalidate()
434 uint64_t cfg = ds->phb->regs[PHB_PHB3_CONFIG >> 3]; in pnv_phb3_update_msi_regions()
437 if (!memory_region_is_mapped(&ds->msi32_mr)) { in pnv_phb3_update_msi_regions()
438 memory_region_add_subregion(MEMORY_REGION(&ds->dma_mr), in pnv_phb3_update_msi_regions()
439 0xffff0000, &ds->msi32_mr); in pnv_phb3_update_msi_regions()
442 if (memory_region_is_mapped(&ds->msi32_mr)) { in pnv_phb3_update_msi_regions()
443 memory_region_del_subregion(MEMORY_REGION(&ds->dma_mr), in pnv_phb3_update_msi_regions()
444 &ds->msi32_mr); in pnv_phb3_update_msi_regions()
449 if (!memory_region_is_mapped(&ds->msi64_mr)) { in pnv_phb3_update_msi_regions()
450 memory_region_add_subregion(MEMORY_REGION(&ds->dma_mr), in pnv_phb3_update_msi_regions()
451 (1ull << 60), &ds->msi64_mr); in pnv_phb3_update_msi_regions()
454 if (memory_region_is_mapped(&ds->msi64_mr)) { in pnv_phb3_update_msi_regions()
455 memory_region_del_subregion(MEMORY_REGION(&ds->dma_mr), in pnv_phb3_update_msi_regions()
456 &ds->msi64_mr); in pnv_phb3_update_msi_regions()
465 QLIST_FOREACH(ds, &phb->dma_spaces, list) { in pnv_phb3_update_all_msi_regions()
481 /* Other registers are 64-bit only */ in pnv_phb3_reg_write()
506 phb->regs[PHB_LEM_FIR_ACCUM >> 3] &= val; in pnv_phb3_reg_write()
509 phb->regs[PHB_LEM_FIR_ACCUM >> 3] |= val; in pnv_phb3_reg_write()
512 phb->regs[PHB_LEM_ERROR_MASK >> 3] &= val; in pnv_phb3_reg_write()
515 phb->regs[PHB_LEM_ERROR_MASK >> 3] |= val; in pnv_phb3_reg_write()
523 changed = phb->regs[off >> 3] != val; in pnv_phb3_reg_write()
526 phb->regs[off >> 3] = val; in pnv_phb3_reg_write()
565 pnv_phb3_msi_ffi(&phb->msis, val); in pnv_phb3_reg_write()
595 PCIHostState *pci = PCI_HOST_BRIDGE(phb->phb_base); in pnv_phb3_reg_read()
602 /* Other registers are 64-bit only */ in pnv_phb3_reg_read()
610 val = phb->regs[off >> 3]; in pnv_phb3_reg_read()
625 if (!pci_find_device(pci->bus, 1, 0)) { in pnv_phb3_reg_read()
633 phb->regs[off >> 3] |= PHB_FFI_LOCK_STATE; in pnv_phb3_reg_read()
694 qemu_set_irq(phb->qirqs[irq_num], level); in pnv_phb3_set_irq()
704 if (ds->pe_num != PHB_INVALID_PE) { in pnv_phb3_resolve_pe()
709 rtt = ds->phb->regs[PHB_RTT_BAR >> 3]; in pnv_phb3_resolve_pe()
711 phb3_error(ds->phb, "DMA with RTT BAR disabled !"); in pnv_phb3_resolve_pe()
717 bus_num = pci_bus_num(ds->bus); in pnv_phb3_resolve_pe()
719 addr += 2 * ((bus_num << 8) | ds->devfn); in pnv_phb3_resolve_pe()
722 phb3_error(ds->phb, "Failed to read RTT entry at 0x%"PRIx64, addr); in pnv_phb3_resolve_pe()
730 phb3_error(ds->phb, "RTE for RID 0x%x invalid (%04x", ds->devfn, rte); in pnv_phb3_resolve_pe()
734 ds->pe_num = rte; in pnv_phb3_resolve_pe()
746 PnvPHB3 *phb = ds->phb; in pnv_phb3_translate_tve()
757 * We only support non-translate in top window. in pnv_phb3_translate_tve()
763 phb3_error(phb, "xlate for invalid non-translate TVE"); in pnv_phb3_translate_tve()
769 tlb->iova = addr & 0xfffffffffffff000ull; in pnv_phb3_translate_tve()
770 tlb->translated_addr = addr & 0x0003fffffffff000ull; in pnv_phb3_translate_tve()
771 tlb->addr_mask = 0xfffull; in pnv_phb3_translate_tve()
772 tlb->perm = IOMMU_RW; in pnv_phb3_translate_tve()
795 /* TODO: Multi-level untested */ in pnv_phb3_translate_tve()
797 lev--; in pnv_phb3_translate_tve()
800 taddr = base | (((addr >> sh) & ((1ul << tbl_shift) - 1)) << 3); in pnv_phb3_translate_tve()
817 sh -= tbl_shift; in pnv_phb3_translate_tve()
830 tce_mask = ~((1ull << tce_shift) - 1); in pnv_phb3_translate_tve()
831 tlb->iova = addr & tce_mask; in pnv_phb3_translate_tve()
832 tlb->translated_addr = tce & tce_mask; in pnv_phb3_translate_tve()
833 tlb->addr_mask = ~tce_mask; in pnv_phb3_translate_tve()
834 tlb->perm = tce & 3; in pnv_phb3_translate_tve()
853 PnvPHB3 *phb = ds->phb; in pnv_phb3_translate_iommu()
858 ds->bus, pci_bus_num(ds->bus), ds->devfn); in pnv_phb3_translate_iommu()
865 /* DMA or 32-bit MSI ? */ in pnv_phb3_translate_iommu()
866 cfg = ds->phb->regs[PHB_PHB3_CONFIG >> 3]; in pnv_phb3_translate_iommu()
869 phb3_error(phb, "xlate on 32-bit MSI region"); in pnv_phb3_translate_iommu()
874 tve = ds->phb->ioda_TVT[ds->pe_num * 2 + tve_sel]; in pnv_phb3_translate_iommu()
878 phb3_error(phb, "xlate on 64-bit MSI region"); in pnv_phb3_translate_iommu()
886 #define TYPE_PNV_PHB3_IOMMU_MEMORY_REGION "pnv-phb3-iommu-memory-region"
895 imrc->translate = pnv_phb3_translate_iommu; in DECLARE_INSTANCE_CHECKER()
915 phb3_error(ds->phb, "Failed to resolve PE# for bus @%p (%d) devfn 0x%x", in pnv_phb3_msi_write()
916 ds->bus, pci_bus_num(ds->bus), ds->devfn); in pnv_phb3_msi_write()
920 pnv_phb3_msi_send(&ds->phb->msis, addr, data, ds->pe_num); in pnv_phb3_msi_write()
928 phb3_error(ds->phb, "invalid read @ 0x%" HWADDR_PRIx, addr); in pnv_phb3_msi_read()
929 return -1; in pnv_phb3_msi_read()
943 QLIST_FOREACH(ds, &phb->dma_spaces, list) { in pnv_phb3_dma_iommu()
944 if (ds->bus == bus && ds->devfn == devfn) { in pnv_phb3_dma_iommu()
951 ds->bus = bus; in pnv_phb3_dma_iommu()
952 ds->devfn = devfn; in pnv_phb3_dma_iommu()
953 ds->pe_num = PHB_INVALID_PE; in pnv_phb3_dma_iommu()
954 ds->phb = phb; in pnv_phb3_dma_iommu()
955 memory_region_init_iommu(&ds->dma_mr, sizeof(ds->dma_mr), in pnv_phb3_dma_iommu()
958 address_space_init(&ds->dma_as, MEMORY_REGION(&ds->dma_mr), in pnv_phb3_dma_iommu()
960 memory_region_init_io(&ds->msi32_mr, OBJECT(phb), &pnv_phb3_msi_ops, in pnv_phb3_dma_iommu()
962 memory_region_init_io(&ds->msi64_mr, OBJECT(phb), &pnv_phb3_msi_ops, in pnv_phb3_dma_iommu()
966 QLIST_INSERT_HEAD(&phb->dma_spaces, ds, list); in pnv_phb3_dma_iommu()
968 return &ds->dma_as; in pnv_phb3_dma_iommu()
979 QLIST_INIT(&phb->dma_spaces); in pnv_phb3_instance_init()
982 object_initialize_child(obj, "lsi", &phb->lsis, TYPE_ICS); in pnv_phb3_instance_init()
985 phb->lsis.offset = 0; in pnv_phb3_instance_init()
988 object_initialize_child(obj, "msi", &phb->msis, TYPE_PHB3_MSI); in pnv_phb3_instance_init()
991 object_initialize_child(obj, "pbcq", &phb->pbcq, TYPE_PNV_PBCQ); in pnv_phb3_instance_init()
1004 memory_region_init(&phb->pci_io, OBJECT(phb), "pci-io", 0x10000); in pnv_phb3_bus_init()
1005 memory_region_init(&phb->pci_mmio, OBJECT(phb), "pci-mmio", in pnv_phb3_bus_init()
1008 pci->bus = pci_register_root_bus(dev, in pnv_phb3_bus_init()
1009 dev->id ? dev->id : NULL, in pnv_phb3_bus_init()
1011 &phb->pci_mmio, &phb->pci_io, in pnv_phb3_bus_init()
1014 object_property_set_int(OBJECT(pci->bus), "phb-id", phb->phb_id, in pnv_phb3_bus_init()
1016 object_property_set_int(OBJECT(pci->bus), "chip-id", phb->chip_id, in pnv_phb3_bus_init()
1019 pci_setup_iommu(pci->bus, &pnv_phb3_iommu_ops, phb); in pnv_phb3_bus_init()
1028 if (phb->phb_id >= PNV_CHIP_GET_CLASS(phb->chip)->num_phbs) { in pnv_phb3_realize()
1029 error_setg(errp, "invalid PHB index: %d", phb->phb_id); in pnv_phb3_realize()
1034 object_property_set_link(OBJECT(&phb->lsis), "xics", OBJECT(pnv), in pnv_phb3_realize()
1036 object_property_set_int(OBJECT(&phb->lsis), "nr-irqs", PNV_PHB3_NUM_LSI, in pnv_phb3_realize()
1038 if (!qdev_realize(DEVICE(&phb->lsis), NULL, errp)) { in pnv_phb3_realize()
1042 for (i = 0; i < phb->lsis.nr_irqs; i++) { in pnv_phb3_realize()
1043 ics_set_irq_type(&phb->lsis, i, true); in pnv_phb3_realize()
1046 phb->qirqs = qemu_allocate_irqs(ics_set_irq, &phb->lsis, phb->lsis.nr_irqs); in pnv_phb3_realize()
1049 object_property_set_link(OBJECT(&phb->msis), "phb", OBJECT(phb), in pnv_phb3_realize()
1051 object_property_set_link(OBJECT(&phb->msis), "xics", OBJECT(pnv), in pnv_phb3_realize()
1053 object_property_set_int(OBJECT(&phb->msis), "nr-irqs", PHB3_MAX_MSI, in pnv_phb3_realize()
1055 if (!qdev_realize(DEVICE(&phb->msis), NULL, errp)) { in pnv_phb3_realize()
1060 object_property_set_link(OBJECT(&phb->pbcq), "phb", OBJECT(phb), in pnv_phb3_realize()
1062 if (!qdev_realize(DEVICE(&phb->pbcq), NULL, errp)) { in pnv_phb3_realize()
1067 memory_region_init_io(&phb->mr_regs, OBJECT(phb), &pnv_phb3_reg_ops, phb, in pnv_phb3_realize()
1068 "phb3-regs", 0x1000); in pnv_phb3_realize()
1073 PnvPBCQState *pbcq = &phb->pbcq; in pnv_phb3_update_regions()
1076 if (memory_region_is_mapped(&phb->mr_regs)) { in pnv_phb3_update_regions()
1077 memory_region_del_subregion(&pbcq->phbbar, &phb->mr_regs); in pnv_phb3_update_regions()
1081 if (memory_region_is_mapped(&pbcq->phbbar)) { in pnv_phb3_update_regions()
1083 memory_region_add_subregion(&pbcq->phbbar, 0, &phb->mr_regs); in pnv_phb3_update_regions()
1087 if (memory_region_is_mapped(&phb->mr_m32)) { in pnv_phb3_update_regions()
1095 DEFINE_PROP_UINT32("chip-id", PnvPHB3, chip_id, 0),
1097 DEFINE_PROP_LINK("phb-base", PnvPHB3, phb_base, TYPE_PNV_PHB, PnvPHB *),
1105 dc->realize = pnv_phb3_realize; in pnv_phb3_class_init()
1107 dc->user_creatable = false; in pnv_phb3_class_init()
1125 if (strcmp(name, "phb-id") == 0) { in pnv_phb3_root_bus_get_prop()
1126 value = bus->phb_id; in pnv_phb3_root_bus_get_prop()
1128 value = bus->chip_id; in pnv_phb3_root_bus_get_prop()
1146 if (strcmp(name, "phb-id") == 0) { in pnv_phb3_root_bus_set_prop()
1147 bus->phb_id = value; in pnv_phb3_root_bus_set_prop()
1149 bus->chip_id = value; in pnv_phb3_root_bus_set_prop()
1157 object_class_property_add(klass, "phb-id", "int", in pnv_phb3_root_bus_class_init()
1162 object_class_property_add(klass, "chip-id", "int", in pnv_phb3_root_bus_class_init()
1171 k->max_dev = 1; in pnv_phb3_root_bus_class_init()