/* * Map mailbox memory with attribute device nGnRE (ie ioremap - * this deviates from the parking protocol specifications since * the mailboxes are required to be mapped nGnRnE; the attribute * discrepancy is harmless insofar as the protocol specification * is concerned). * If the mailbox is mistakenly allocated in the linear mapping * by FW ioremap will fail since the mapping will be prevented * by the kernel (it clashes with the linear mapping attributes * specifications).
*/
mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox)); if (!mailbox) return -EIO;
cpu_id = readl_relaxed(&mailbox->cpu_id); /* * Check if firmware has set-up the mailbox entry properly * before kickstarting the respective cpu.
*/ if (cpu_id != ~0U) {
iounmap(mailbox); return -ENXIO;
}
/* * stash the mailbox address mapping to use it for further FW * checks in the postboot method
*/
cpu_entry->mailbox = mailbox;
/* * We write the entry point and cpu id 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.
*/
writeq_relaxed(__pa_symbol(secondary_entry),
&mailbox->entry_point);
writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
arch_send_wakeup_ipi(cpu);
return 0;
}
staticvoid acpi_parking_protocol_cpu_postboot(void)
{ int cpu = smp_processor_id(); struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu]; struct parking_protocol_mailbox __iomem *mailbox = cpu_entry->mailbox;
u64 entry_point;
entry_point = readq_relaxed(&mailbox->entry_point); /* * Check if firmware has cleared the entry_point as expected * by the protocol specification.
*/
WARN_ON(entry_point);
}
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.