drivers/iommu/riscv/iommu.c
Source file repositories/reference/linux-study-clean/drivers/iommu/riscv/iommu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/riscv/iommu.c- Extension
.c- Size
- 47978 bytes
- Lines
- 1629
- Domain
- Driver Families
- Bucket
- drivers/iommu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/acpi.hlinux/acpi_rimt.hlinux/compiler.hlinux/crash_dump.hlinux/init.hlinux/iommu.hlinux/iopoll.hlinux/kernel.hlinux/pci.hlinux/generic_pt/iommu.h../iommu-pages.hiommu-bits.hiommu.h
Detected Declarations
struct riscv_iommu_devresstruct riscv_iommu_domainstruct riscv_iommu_infostruct riscv_iommu_bondstruct riscv_iommu_tlbifunction riscv_iommu_devres_pages_releasefunction riscv_iommu_devres_pages_matchfunction riscv_iommu_free_pagesfunction riscv_iommu_queue_allocfunction riscv_iommu_queue_ipsrfunction riscv_iommu_queue_vecfunction riscv_iommu_queue_enablefunction riscv_iommu_queue_disablefunction riscv_iommu_queue_consumefunction riscv_iommu_queue_releasefunction riscv_iommu_queue_consfunction riscv_iommu_queue_waitfunction riscv_iommu_queue_sendfunction riscv_iommu_cmdq_processfunction riscv_iommu_cmd_sendfunction riscv_iommu_cmd_syncfunction riscv_iommu_faultfunction riscv_iommu_fltq_processfunction riscv_iommu_disablefunction riscv_iommu_iodir_allocfunction riscv_iommu_iodir_set_modefunction riscv_iommu_bond_linkfunction riscv_iommu_bond_unlinkfunction riscv_iommu_tlbi_calcfunction riscv_iommu_iotlb_inval_iommufunction riscv_iommu_iotlb_invalfunction specificationfunction riscv_iommu_probe_devicefunction riscv_iommu_iotlb_flush_allfunction riscv_iommu_iotlb_syncfunction riscv_iommu_free_paging_domainfunction riscv_iommu_pt_supportedfunction riscv_iommu_attach_paging_domainfunction riscv_iommu_attach_blocking_domainfunction riscv_iommu_attach_identity_domainfunction riscv_iommu_of_xlatefunction riscv_iommu_release_devicefunction riscv_iommu_init_checkfunction riscv_iommu_removefunction riscv_iommu_init
Annotated Snippet
struct riscv_iommu_devres {
void *addr;
};
static void riscv_iommu_devres_pages_release(struct device *dev, void *res)
{
struct riscv_iommu_devres *devres = res;
iommu_free_pages(devres->addr);
}
static int riscv_iommu_devres_pages_match(struct device *dev, void *res, void *p)
{
struct riscv_iommu_devres *devres = res;
struct riscv_iommu_devres *target = p;
return devres->addr == target->addr;
}
static void *riscv_iommu_get_pages(struct riscv_iommu_device *iommu,
unsigned int size)
{
struct riscv_iommu_devres *devres;
void *addr;
addr = iommu_alloc_pages_node_sz(dev_to_node(iommu->dev),
GFP_KERNEL_ACCOUNT, size);
if (unlikely(!addr))
return NULL;
devres = devres_alloc(riscv_iommu_devres_pages_release,
sizeof(struct riscv_iommu_devres), GFP_KERNEL);
if (unlikely(!devres)) {
iommu_free_pages(addr);
return NULL;
}
devres->addr = addr;
devres_add(iommu->dev, devres);
return addr;
}
static void riscv_iommu_free_pages(struct riscv_iommu_device *iommu, void *addr)
{
struct riscv_iommu_devres devres = { .addr = addr };
devres_release(iommu->dev, riscv_iommu_devres_pages_release,
riscv_iommu_devres_pages_match, &devres);
}
/*
* Hardware queue allocation and management.
*/
/* Setup queue base, control registers and default queue length */
#define RISCV_IOMMU_QUEUE_INIT(q, name) do { \
struct riscv_iommu_queue *_q = q; \
_q->qid = RISCV_IOMMU_INTR_ ## name; \
_q->qbr = RISCV_IOMMU_REG_ ## name ## B; \
_q->qcr = RISCV_IOMMU_REG_ ## name ## CSR; \
_q->mask = _q->mask ?: (RISCV_IOMMU_DEF_ ## name ## _COUNT) - 1;\
} while (0)
/* Note: offsets are the same for all queues */
#define Q_HEAD(q) ((q)->qbr + (RISCV_IOMMU_REG_CQH - RISCV_IOMMU_REG_CQB))
#define Q_TAIL(q) ((q)->qbr + (RISCV_IOMMU_REG_CQT - RISCV_IOMMU_REG_CQB))
#define Q_ITEM(q, index) ((q)->mask & (index))
#define Q_IPSR(q) BIT((q)->qid)
/*
* Discover queue ring buffer hardware configuration, allocate in-memory
* ring buffer or use fixed I/O memory location, configure queue base register.
* Must be called before hardware queue is enabled.
*
* @queue - data structure, configured with RISCV_IOMMU_QUEUE_INIT()
* @entry_size - queue single element size in bytes.
*/
static int riscv_iommu_queue_alloc(struct riscv_iommu_device *iommu,
struct riscv_iommu_queue *queue,
size_t entry_size)
{
unsigned int logsz;
u64 qb, rb;
/*
* Use WARL base register property to discover maximum allowed
* number of entries and optional fixed IO address for queue location.
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/acpi_rimt.h`, `linux/compiler.h`, `linux/crash_dump.h`, `linux/init.h`, `linux/iommu.h`, `linux/iopoll.h`, `linux/kernel.h`.
- Detected declarations: `struct riscv_iommu_devres`, `struct riscv_iommu_domain`, `struct riscv_iommu_info`, `struct riscv_iommu_bond`, `struct riscv_iommu_tlbi`, `function riscv_iommu_devres_pages_release`, `function riscv_iommu_devres_pages_match`, `function riscv_iommu_free_pages`, `function riscv_iommu_queue_alloc`, `function riscv_iommu_queue_ipsr`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: source 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.