/* * Write secondary_holding_pen_release in a way that is guaranteed to be * visible to all observers, irrespective of whether they're taking part * in coherency or not. This is necessary for the hotplug code to work * reliably.
*/ staticvoid write_pen_release(u64 val)
{ void *start = (void *)&secondary_holding_pen_release; unsignedlong size = sizeof(secondary_holding_pen_release);
staticint smp_spin_table_cpu_init(unsignedint cpu)
{ struct device_node *dn; int ret;
dn = of_get_cpu_node(cpu, NULL); if (!dn) return -ENODEV;
/* * Determine the address from which the CPU is polling.
*/
ret = of_property_read_u64(dn, "cpu-release-addr",
&cpu_release_addr[cpu]); if (ret)
pr_err("CPU %d: missing or invalid cpu-release-addr property\n",
cpu);
/* * The cpu-release-addr may or may not be inside the linear mapping. * As ioremap_cache will either give us a new mapping or reuse the * existing linear mapping, we can use it to cover both cases. In * either case the memory will be MT_NORMAL.
*/
release_addr = ioremap_cache(cpu_release_addr[cpu], sizeof(*release_addr)); if (!release_addr) return -ENOMEM;
/* * We write the release address as LE regardless of the native * endianness of the kernel. Therefore, any boot-loaders that * read this address need to convert this address to the * boot-loader's endianness before jumping. This is mandated by * the boot protocol.
*/
writeq_relaxed(pa_holding_pen, release_addr);
dcache_clean_inval_poc((__force unsignedlong)release_addr,
(__force unsignedlong)release_addr + sizeof(*release_addr));
/* * Send an event to wake up the secondary CPU.
*/
sev();
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.