0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/acpi.h>
0009 #include <linux/mm.h>
0010 #include <linux/types.h>
0011
0012 #include <asm/cpu_ops.h>
0013
0014 struct parking_protocol_mailbox {
0015 __le32 cpu_id;
0016 __le32 reserved;
0017 __le64 entry_point;
0018 };
0019
0020 struct cpu_mailbox_entry {
0021 struct parking_protocol_mailbox __iomem *mailbox;
0022 phys_addr_t mailbox_addr;
0023 u8 version;
0024 u8 gic_cpu_id;
0025 };
0026
0027 static struct cpu_mailbox_entry cpu_mailbox_entries[NR_CPUS];
0028
0029 void __init acpi_set_mailbox_entry(int cpu,
0030 struct acpi_madt_generic_interrupt *p)
0031 {
0032 struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
0033
0034 cpu_entry->mailbox_addr = p->parked_address;
0035 cpu_entry->version = p->parking_version;
0036 cpu_entry->gic_cpu_id = p->cpu_interface_number;
0037 }
0038
0039 bool acpi_parking_protocol_valid(int cpu)
0040 {
0041 struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
0042
0043 return cpu_entry->mailbox_addr && cpu_entry->version;
0044 }
0045
0046 static int acpi_parking_protocol_cpu_init(unsigned int cpu)
0047 {
0048 pr_debug("%s: ACPI parked addr=%llx\n", __func__,
0049 cpu_mailbox_entries[cpu].mailbox_addr);
0050
0051 return 0;
0052 }
0053
0054 static int acpi_parking_protocol_cpu_prepare(unsigned int cpu)
0055 {
0056 return 0;
0057 }
0058
0059 static int acpi_parking_protocol_cpu_boot(unsigned int cpu)
0060 {
0061 struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
0062 struct parking_protocol_mailbox __iomem *mailbox;
0063 u32 cpu_id;
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox));
0077 if (!mailbox)
0078 return -EIO;
0079
0080 cpu_id = readl_relaxed(&mailbox->cpu_id);
0081
0082
0083
0084
0085 if (cpu_id != ~0U) {
0086 iounmap(mailbox);
0087 return -ENXIO;
0088 }
0089
0090
0091
0092
0093
0094 cpu_entry->mailbox = mailbox;
0095
0096
0097
0098
0099
0100
0101
0102 writeq_relaxed(__pa_symbol(function_nocfi(secondary_entry)),
0103 &mailbox->entry_point);
0104 writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
0105
0106 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
0107
0108 return 0;
0109 }
0110
0111 static void acpi_parking_protocol_cpu_postboot(void)
0112 {
0113 int cpu = smp_processor_id();
0114 struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
0115 struct parking_protocol_mailbox __iomem *mailbox = cpu_entry->mailbox;
0116 u64 entry_point;
0117
0118 entry_point = readq_relaxed(&mailbox->entry_point);
0119
0120
0121
0122
0123 WARN_ON(entry_point);
0124 }
0125
0126 const struct cpu_operations acpi_parking_protocol_ops = {
0127 .name = "parking-protocol",
0128 .cpu_init = acpi_parking_protocol_cpu_init,
0129 .cpu_prepare = acpi_parking_protocol_cpu_prepare,
0130 .cpu_boot = acpi_parking_protocol_cpu_boot,
0131 .cpu_postboot = acpi_parking_protocol_cpu_postboot
0132 };