drivers/edac/versal_edac.c
Source file repositories/reference/linux-study-clean/drivers/edac/versal_edac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/edac/versal_edac.c- Extension
.c- Size
- 32786 bytes
- Lines
- 1197
- Domain
- Driver Families
- Bucket
- drivers/edac
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/edac.hlinux/interrupt.hlinux/module.hlinux/of.hlinux/of_address.hlinux/of_device.hlinux/platform_device.hlinux/sizes.hlinux/firmware/xlnx-zynqmp.hlinux/firmware/xlnx-event-manager.hedac_module.h
Detected Declarations
struct ecc_statusstruct edac_privfunction get_ce_error_infofunction get_ue_error_infofunction get_error_infofunction convert_to_physicalfunction handle_errorfunction err_callbackfunction get_dwidthfunction get_ecc_statefunction get_memsizefunction init_csrowsfunction mc_initfunction enable_intrfunction disable_intrfunction poison_setupfunction xddr_inject_data_ce_storefunction xddr_inject_data_ce_storefunction xddr_inject_data_ue_storefunction xddr_inject_data_ue_storefunction create_debugfs_attributesfunction process_bitfunction setup_row_address_mapfunction setup_column_address_mapfunction setup_bank_grp_ch_address_mapfunction setup_rank_lrank_address_mapfunction setup_address_mapfunction emif_get_idfunction for_each_matching_nodefunction mc_probefunction mc_remove
Annotated Snippet
static const struct file_operations xddr_inject_ce_fops = {
.open = simple_open,
.write = inject_data_ce_store,
.llseek = generic_file_llseek,
};
static void xddr_inject_data_ue_store(struct mem_ctl_info *mci, u32 val0, u32 val1)
{
struct edac_priv *priv = mci->pvt_info;
writel(val0, priv->ddrmc_baseaddr + ECCW0_FLIP0_OFFSET);
writel(val0, priv->ddrmc_baseaddr + ECCW0_FLIP1_OFFSET);
writel(val1, priv->ddrmc_baseaddr + ECCW1_FLIP1_OFFSET);
writel(val1, priv->ddrmc_baseaddr + ECCW1_FLIP1_OFFSET);
}
/*
* To inject an uncorrectable error, the following steps are needed:
* echo <bit_pos val> > /sys/kernel/debug/edac/<controller instance>/inject_ue
*
* poison_setup() derives the row, column, bank, group and rank and
* writes to the ADEC registers based on the address given by the user.
*
* The ADEC12 and ADEC13 are mask registers; write 0 so that none of the
* addresses are masked. The row, column, bank, group and rank registers
* are written to the match ADEC bit to generate errors at the
* particular address. ADEC14 and ADEC15 have the match bits.
*
* xddr_inject_data_ue_store() updates the ECC FLIP registers with the
* bits to be corrupted based on the bit position given by the user. For
* uncorrectable errors
* 2 bit errors are injected.
*
* Upon doing a read to the address the errors are injected.
*/
static ssize_t inject_data_ue_store(struct file *file, const char __user *data,
size_t count, loff_t *ppos)
{
struct device *dev = file->private_data;
struct mem_ctl_info *mci = to_mci(dev);
struct edac_priv *priv = mci->pvt_info;
char buf[6], *pbuf, *token[2];
u32 val0 = 0, val1 = 0;
u8 len, ue0, ue1;
int i, ret;
len = min_t(size_t, count, sizeof(buf));
if (copy_from_user(buf, data, len))
return -EFAULT;
buf[len] = '\0';
pbuf = &buf[0];
for (i = 0; i < NUM_UE_BITPOS; i++)
token[i] = strsep(&pbuf, ",");
if (!token[0] || !token[1])
return -EFAULT;
ret = kstrtou8(token[0], 0, &ue0);
if (ret)
return ret;
ret = kstrtou8(token[1], 0, &ue1);
if (ret)
return ret;
if (ue0 < ECCW0_FLIP0_BITS) {
val0 = BIT(ue0);
} else {
ue0 = ue0 - ECCW0_FLIP0_BITS;
val1 = BIT(ue0);
}
if (ue1 < ECCW0_FLIP0_BITS) {
val0 |= BIT(ue1);
} else {
ue1 = ue1 - ECCW0_FLIP0_BITS;
val1 |= BIT(ue1);
}
/* Unlock the PCSR registers */
writel(PCSR_UNLOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET);
writel(PCSR_UNLOCK_VAL, priv->ddrmc_noc_baseaddr + XDDR_PCSR_OFFSET);
poison_setup(priv);
xddr_inject_data_ue_store(mci, val0, val1);
/* Lock the PCSR registers */
writel(PCSR_LOCK_VAL, priv->ddrmc_noc_baseaddr + XDDR_PCSR_OFFSET);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/edac.h`, `linux/interrupt.h`, `linux/module.h`, `linux/of.h`, `linux/of_address.h`, `linux/of_device.h`, `linux/platform_device.h`.
- Detected declarations: `struct ecc_status`, `struct edac_priv`, `function get_ce_error_info`, `function get_ue_error_info`, `function get_error_info`, `function convert_to_physical`, `function handle_error`, `function err_callback`, `function get_dwidth`, `function get_ecc_state`.
- Atlas domain: Driver Families / drivers/edac.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.