arch/powerpc/platforms/powernv/pci-ioda.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/pci-ioda.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/powernv/pci-ioda.c- Extension
.c- Size
- 75067 bytes
- Lines
- 2750
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/pci.hlinux/crash_dump.hlinux/delay.hlinux/string.hlinux/init.hlinux/memblock.hlinux/irq.hlinux/irqchip/irq-msi-lib.hlinux/io.hlinux/msi.hlinux/iommu.hlinux/rculist.hlinux/sizes.hlinux/debugfs.hlinux/of_address.hlinux/of_irq.hasm/sections.hasm/io.hasm/pci-bridge.hasm/machdep.hasm/msi_bitmap.hasm/ppc-pci.hasm/opal.hasm/iommu.hasm/tce.hasm/xics.hasm/firmware.hasm/pnv-pci.hasm/mmzone.hpowernv.hpci.h
Detected Declarations
function pe_level_printkfunction iommu_setupfunction pci_reset_phbs_setupfunction pnv_ioda_reserve_pefunction pnv_ioda_free_pefunction pnv_ioda2_init_m64function pnv_ioda_reserve_dev_m64_pefunction pnv_ioda_reserve_m64_pefunction list_for_each_entryfunction pnv_ioda_parse_m64_windowfunction pnv_ioda_freeze_pefunction list_for_each_entryfunction pnv_ioda_unfreeze_pefunction pnv_ioda_get_pe_statefunction list_for_each_entryfunction pnv_ioda_set_one_peltvfunction pnv_ioda_set_peltvfunction list_for_each_entryfunction pnv_ioda_unset_peltvfunction pnv_ioda_deconfigure_pefunction pnv_ioda_configure_pefunction pnv_pci_ioda_dma_dev_setupfunction PHB3function pnv_pci_ioda_iommu_bypass_supportedfunction pnv_ioda_tce_xchg_no_killfunction pnv_pci_phb3_tce_invalidate_pefunction pnv_pci_phb3_tce_invalidatefunction pnv_pci_ioda2_tce_invalidate_pefunction pnv_pci_ioda2_tce_invalidatefunction list_for_each_entry_locklessfunction pnv_ioda2_tce_buildfunction pnv_ioda2_tce_freefunction pnv_pci_ioda2_set_windowfunction pnv_pci_ioda2_set_bypassfunction pnv_pci_ioda2_create_tablefunction pnv_pci_ioda2_setup_default_configfunction pnv_pci_ioda2_unset_windowfunction pnv_pci_ioda2_get_table_sizefunction pnv_pci_ioda2_create_table_userspacefunction pnv_ioda_setup_bus_dmafunction list_for_each_entryfunction pnv_ioda2_take_ownershipfunction pnv_ioda2_release_ownershipfunction pnv_pci_ioda2_setup_dma_pefunction kvmppc_deliver_irq_passthrufunction is_pnv_opal_msifunction __pnv_pci_ioda_msi_setupfunction pnv_msi_shutdown
Annotated Snippet
if (!strncmp(str, "nobypass", 8)) {
pnv_iommu_bypass_disabled = true;
pr_info("PowerNV: IOMMU bypass window disabled.\n");
break;
}
str += strcspn(str, ",");
if (*str == ',')
str++;
}
return 0;
}
early_param("iommu", iommu_setup);
static int __init pci_reset_phbs_setup(char *str)
{
pci_reset_phbs = true;
return 0;
}
early_param("ppc_pci_reset_phbs", pci_reset_phbs_setup);
static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb *phb, int pe_no)
{
s64 rc;
phb->ioda.pe_array[pe_no].phb = phb;
phb->ioda.pe_array[pe_no].pe_number = pe_no;
phb->ioda.pe_array[pe_no].dma_setup_done = false;
/*
* Clear the PE frozen state as it might be put into frozen state
* in the last PCI remove path. It's not harmful to do so when the
* PE is already in unfrozen state.
*/
rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
if (rc != OPAL_SUCCESS && rc != OPAL_UNSUPPORTED)
pr_warn("%s: Error %lld unfreezing PHB#%x-PE#%x\n",
__func__, rc, phb->hose->global_number, pe_no);
return &phb->ioda.pe_array[pe_no];
}
static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
{
if (!(pe_no >= 0 && pe_no < phb->ioda.total_pe_num)) {
pr_warn("%s: Invalid PE %x on PHB#%x\n",
__func__, pe_no, phb->hose->global_number);
return;
}
mutex_lock(&phb->ioda.pe_alloc_mutex);
if (test_and_set_bit(pe_no, phb->ioda.pe_alloc))
pr_debug("%s: PE %x was reserved on PHB#%x\n",
__func__, pe_no, phb->hose->global_number);
mutex_unlock(&phb->ioda.pe_alloc_mutex);
pnv_ioda_init_pe(phb, pe_no);
}
struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb, int count)
{
struct pnv_ioda_pe *ret = NULL;
int run = 0, pe, i;
mutex_lock(&phb->ioda.pe_alloc_mutex);
/* scan backwards for a run of @count cleared bits */
for (pe = phb->ioda.total_pe_num - 1; pe >= 0; pe--) {
if (test_bit(pe, phb->ioda.pe_alloc)) {
run = 0;
continue;
}
run++;
if (run == count)
break;
}
if (run != count)
goto out;
for (i = pe; i < pe + count; i++) {
set_bit(i, phb->ioda.pe_alloc);
pnv_ioda_init_pe(phb, i);
}
ret = &phb->ioda.pe_array[pe];
out:
mutex_unlock(&phb->ioda.pe_alloc_mutex);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/pci.h`, `linux/crash_dump.h`, `linux/delay.h`, `linux/string.h`, `linux/init.h`, `linux/memblock.h`, `linux/irq.h`.
- Detected declarations: `function pe_level_printk`, `function iommu_setup`, `function pci_reset_phbs_setup`, `function pnv_ioda_reserve_pe`, `function pnv_ioda_free_pe`, `function pnv_ioda2_init_m64`, `function pnv_ioda_reserve_dev_m64_pe`, `function pnv_ioda_reserve_m64_pe`, `function list_for_each_entry`, `function pnv_ioda_parse_m64_window`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.