arch/powerpc/sysdev/xics/icp-hv.c
Source file repositories/reference/linux-study-clean/arch/powerpc/sysdev/xics/icp-hv.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/sysdev/xics/icp-hv.c- Extension
.c- Size
- 3840 bytes
- Lines
- 182
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: implementation source
- Status
- source 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/kernel.hlinux/irq.hlinux/smp.hlinux/interrupt.hlinux/irqdomain.hlinux/cpu.hlinux/of.hasm/smp.hasm/irq.hasm/errno.hasm/xics.hasm/io.hasm/hvcall.h
Detected Declarations
function icp_hv_get_xirrfunction icp_hv_set_cpprfunction icp_hv_set_xirrfunction icp_hv_set_qirrfunction icp_hv_eoifunction icp_hv_teardown_cpufunction icp_hv_flush_ipifunction icp_hv_get_irqfunction icp_hv_set_cpu_priorityfunction icp_hv_cause_ipifunction icp_hv_ipi_actionfunction icp_hv_init
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2011 IBM Corporation.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/cpu.h>
#include <linux/of.h>
#include <asm/smp.h>
#include <asm/irq.h>
#include <asm/errno.h>
#include <asm/xics.h>
#include <asm/io.h>
#include <asm/hvcall.h>
static inline unsigned int icp_hv_get_xirr(unsigned char cppr)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
unsigned int ret = XICS_IRQ_SPURIOUS;
rc = plpar_hcall(H_XIRR, retbuf, cppr);
if (rc == H_SUCCESS) {
ret = (unsigned int)retbuf[0];
} else {
pr_err("%s: bad return code xirr cppr=0x%x returned %ld\n",
__func__, cppr, rc);
WARN_ON_ONCE(1);
}
return ret;
}
static inline void icp_hv_set_cppr(u8 value)
{
long rc = plpar_hcall_norets(H_CPPR, value);
if (rc != H_SUCCESS) {
pr_err("%s: bad return code cppr cppr=0x%x returned %ld\n",
__func__, value, rc);
WARN_ON_ONCE(1);
}
}
static inline void icp_hv_set_xirr(unsigned int value)
{
long rc = plpar_hcall_norets(H_EOI, value);
if (rc != H_SUCCESS) {
pr_err("%s: bad return code eoi xirr=0x%x returned %ld\n",
__func__, value, rc);
WARN_ON_ONCE(1);
icp_hv_set_cppr(value >> 24);
}
}
static inline void icp_hv_set_qirr(int n_cpu , u8 value)
{
int hw_cpu = get_hard_smp_processor_id(n_cpu);
long rc;
/* Make sure all previous accesses are ordered before IPI sending */
mb();
rc = plpar_hcall_norets(H_IPI, hw_cpu, value);
if (rc != H_SUCCESS) {
pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x "
"returned %ld\n", __func__, n_cpu, hw_cpu, value, rc);
WARN_ON_ONCE(1);
}
}
static void icp_hv_eoi(struct irq_data *d)
{
unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
iosync();
icp_hv_set_xirr((xics_pop_cppr() << 24) | hw_irq);
}
static void icp_hv_teardown_cpu(void)
{
int cpu = smp_processor_id();
/* Clear any pending IPI */
icp_hv_set_qirr(cpu, 0xff);
}
Annotation
- Immediate include surface: `linux/types.h`, `linux/kernel.h`, `linux/irq.h`, `linux/smp.h`, `linux/interrupt.h`, `linux/irqdomain.h`, `linux/cpu.h`, `linux/of.h`.
- Detected declarations: `function icp_hv_get_xirr`, `function icp_hv_set_cppr`, `function icp_hv_set_xirr`, `function icp_hv_set_qirr`, `function icp_hv_eoi`, `function icp_hv_teardown_cpu`, `function icp_hv_flush_ipi`, `function icp_hv_get_irq`, `function icp_hv_set_cpu_priority`, `function icp_hv_cause_ipi`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: source implementation candidate.
- 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.