arch/powerpc/platforms/powernv/rng.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/rng.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/powernv/rng.c- Extension
.c- Size
- 4005 bytes
- Lines
- 201
- 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.
- 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/of.hlinux/of_address.hlinux/of_platform.hlinux/slab.hlinux/smp.hasm/archrandom.hasm/cputable.hasm/io.hasm/prom.hasm/machdep.hasm/smp.hpowernv.h
Detected Declarations
struct pnv_rngfunction rng_whitenfunction pnv_get_random_darnfunction initialise_darnfunction pnv_get_random_longfunction rng_init_per_cpufunction for_each_possible_cpufunction rng_createfunction pnv_get_random_long_earlyfunction pnv_rng_initfunction pnv_rng_late_initexport pnv_get_random_long
Annotated Snippet
struct pnv_rng {
void __iomem *regs;
void __iomem *regs_real;
unsigned long mask;
};
static DEFINE_PER_CPU(struct pnv_rng *, pnv_rng);
static unsigned long rng_whiten(struct pnv_rng *rng, unsigned long val)
{
unsigned long parity;
/* Calculate the parity of the value */
asm (".machine push; \
.machine power7; \
popcntd %0,%1; \
.machine pop;"
: "=r" (parity) : "r" (val));
/* xor our value with the previous mask */
val ^= rng->mask;
/* update the mask based on the parity of this value */
rng->mask = (rng->mask << 1) | (parity & 1);
return val;
}
static int pnv_get_random_darn(unsigned long *v)
{
unsigned long val;
/* Using DARN with L=1 - 64-bit conditioned random number */
asm volatile(PPC_DARN(%0, 1) : "=r"(val));
if (val == DARN_ERR)
return 0;
*v = val;
return 1;
}
static int __init initialise_darn(void)
{
unsigned long val;
int i;
if (!cpu_has_feature(CPU_FTR_ARCH_300))
return -ENODEV;
for (i = 0; i < 10; i++) {
if (pnv_get_random_darn(&val)) {
ppc_md.get_random_seed = pnv_get_random_darn;
return 0;
}
}
return -EIO;
}
int pnv_get_random_long(unsigned long *v)
{
struct pnv_rng *rng;
if (mfmsr() & MSR_DR) {
rng = get_cpu_var(pnv_rng);
*v = rng_whiten(rng, in_be64(rng->regs));
put_cpu_var(rng);
} else {
rng = raw_cpu_read(pnv_rng);
*v = rng_whiten(rng, __raw_rm_readq(rng->regs_real));
}
return 1;
}
EXPORT_SYMBOL_GPL(pnv_get_random_long);
static __init void rng_init_per_cpu(struct pnv_rng *rng,
struct device_node *dn)
{
int chip_id, cpu;
chip_id = of_get_ibm_chip_id(dn);
if (chip_id == -1)
pr_warn("No ibm,chip-id found for %pOF.\n", dn);
for_each_possible_cpu(cpu) {
if (per_cpu(pnv_rng, cpu) == NULL ||
cpu_to_chip_id(cpu) == chip_id) {
per_cpu(pnv_rng, cpu) = rng;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/of.h`, `linux/of_address.h`, `linux/of_platform.h`, `linux/slab.h`, `linux/smp.h`, `asm/archrandom.h`, `asm/cputable.h`.
- Detected declarations: `struct pnv_rng`, `function rng_whiten`, `function pnv_get_random_darn`, `function initialise_darn`, `function pnv_get_random_long`, `function rng_init_per_cpu`, `function for_each_possible_cpu`, `function rng_create`, `function pnv_get_random_long_early`, `function pnv_rng_init`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: integration implementation candidate.
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.