static u32 drmem_lmb_flags(struct drmem_lmb *lmb)
{ /* * Return the value of the lmb flags field minus the reserved * bit used internally for hotplug processing.
*/ return lmb->flags & ~DRMEM_LMB_RESERVED;
}
p = new_prop->value;
*p++ = cpu_to_be32(lmb_sets);
dr_cell = (struct of_drconf_cell_v2 *)p;
/* Second pass, populate the LMB set data */
prev_lmb = NULL;
seq_lmbs = 0;
for_each_drmem_lmb(lmb) { if (prev_lmb == NULL) { /* Start of first LMB set */
prev_lmb = lmb;
init_drconf_v2_cell(dr_cell, lmb);
seq_lmbs++; continue;
}
if (prev_lmb->aa_index != lmb->aa_index ||
drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb)) { /* end of one set, start of another */
dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
dr_cell++;
/* close out last LMB set */
dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
of_update_property(memory, new_prop); return 0;
}
int drmem_update_dt(void)
{ struct device_node *memory; struct property *prop; int rc = -1;
memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (!memory) return -1;
/* * Set in_drmem_update to prevent the notifier callback to process the * DT property back since the change is coming from the LMB tree.
*/
in_drmem_update = true;
prop = of_find_property(memory, "ibm,dynamic-memory", NULL); if (prop) {
rc = drmem_update_dt_v1(memory, prop);
} else {
prop = of_find_property(memory, "ibm,dynamic-memory-v2", NULL); if (prop)
rc = drmem_update_dt_v2(memory, prop);
}
in_drmem_update = false;
/* * Update the LMB associativity index. * * This needs to be called when the hypervisor is updating the * dynamic-reconfiguration-memory node property.
*/ void drmem_update_lmbs(struct property *prop)
{ /* * Don't update the LMBs if triggered by the update done in * drmem_update_dt(), the LMB values have been used to the update the DT * property in that case.
*/ if (in_drmem_update) return; if (!strcmp(prop->name, "ibm,dynamic-memory"))
__walk_drmem_v1_lmbs(prop->value, NULL, NULL, update_lmb); elseif (!strcmp(prop->name, "ibm,dynamic-memory-v2"))
__walk_drmem_v2_lmbs(prop->value, NULL, NULL, update_lmb);
} #endif
staticint init_drmem_lmb_size(struct device_node *dn)
{ const __be32 *prop; int len;
if (drmem_info->lmb_size) return 0;
prop = of_get_property(dn, "ibm,lmb-size", &len); if (!prop || len < n_root_size_cells * sizeof(__be32)) {
pr_info("Could not determine LMB size\n"); return -1;
}
/* * Returns the property linux,drconf-usable-memory if * it exists (the property exists only in kexec/kdump kernels, * added by kexec-tools)
*/ staticconst __be32 *of_get_usable_memory(struct device_node *dn)
{ const __be32 *prop;
u32 len;
prop = of_get_property(dn, "linux,drconf-usable-memory", &len); if (!prop || len < sizeof(unsignedint)) return NULL;
return prop;
}
int walk_drmem_lmbs(struct device_node *dn, void *data, int (*func)(struct drmem_lmb *, const __be32 **, void *))
{ struct device_node *root = of_find_node_by_path("/"); const __be32 *prop, *usm; int ret = -ENODEV;
if (!root) return ret;
/* Get the address & size cells */
n_root_addr_cells = of_n_addr_cells(root);
n_root_size_cells = of_n_size_cells(root);
of_node_put(root);
if (init_drmem_lmb_size(dn)) return ret;
usm = of_get_usable_memory(dn);
prop = of_get_property(dn, "ibm,dynamic-memory", NULL); if (prop) {
ret = __walk_drmem_v1_lmbs(prop, usm, data, func);
} else {
prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL); if (prop)
ret = __walk_drmem_v2_lmbs(prop, usm, data, func);
}
lmb_sets = of_read_number(prop++, 1); if (lmb_sets == 0) return;
/* first pass, calculate the number of LMBs */
p = prop; for (i = 0; i < lmb_sets; i++) {
read_drconf_v2_cell(&dr_cell, &p);
drmem_info->n_lmbs += dr_cell.seq_lmbs;
}
drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
GFP_KERNEL); if (!drmem_info->lmbs) return;
/* second pass, read in the LMB information */
lmb_index = 0;
p = prop;
for (i = 0; i < lmb_sets; i++) {
read_drconf_v2_cell(&dr_cell, &p);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.