xref: /kernel/linux/linux-5.10/arch/x86/platform/sfi/sfi.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * sfi.c - x86 architecture SFI support.
4 *
5 * Copyright (c) 2009, Intel Corporation.
6 */
7
8#define KMSG_COMPONENT "SFI"
9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
10
11#include <linux/acpi.h>
12#include <linux/init.h>
13#include <linux/sfi.h>
14#include <linux/io.h>
15
16#include <asm/irqdomain.h>
17#include <asm/io_apic.h>
18#include <asm/mpspec.h>
19#include <asm/setup.h>
20#include <asm/apic.h>
21
22#ifdef CONFIG_X86_LOCAL_APIC
23static unsigned long sfi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
24
25/* All CPUs enumerated by SFI must be present and enabled */
26static void __init mp_sfi_register_lapic(u8 id)
27{
28	if (MAX_LOCAL_APIC - id <= 0) {
29		pr_warn("Processor #%d invalid (max %d)\n", id, MAX_LOCAL_APIC);
30		return;
31	}
32
33	pr_info("registering lapic[%d]\n", id);
34
35	generic_processor_info(id, GET_APIC_VERSION(apic_read(APIC_LVR)));
36}
37
38static int __init sfi_parse_cpus(struct sfi_table_header *table)
39{
40	struct sfi_table_simple *sb;
41	struct sfi_cpu_table_entry *pentry;
42	int i;
43	int cpu_num;
44
45	sb = (struct sfi_table_simple *)table;
46	cpu_num = SFI_GET_NUM_ENTRIES(sb, struct sfi_cpu_table_entry);
47	pentry = (struct sfi_cpu_table_entry *)sb->pentry;
48
49	for (i = 0; i < cpu_num; i++) {
50		mp_sfi_register_lapic(pentry->apic_id);
51		pentry++;
52	}
53
54	smp_found_config = 1;
55	return 0;
56}
57#endif /* CONFIG_X86_LOCAL_APIC */
58
59#ifdef CONFIG_X86_IO_APIC
60
61static int __init sfi_parse_ioapic(struct sfi_table_header *table)
62{
63	struct sfi_table_simple *sb;
64	struct sfi_apic_table_entry *pentry;
65	int i, num;
66	struct ioapic_domain_cfg cfg = {
67		.type = IOAPIC_DOMAIN_STRICT,
68		.ops = &mp_ioapic_irqdomain_ops,
69	};
70
71	sb = (struct sfi_table_simple *)table;
72	num = SFI_GET_NUM_ENTRIES(sb, struct sfi_apic_table_entry);
73	pentry = (struct sfi_apic_table_entry *)sb->pentry;
74
75	for (i = 0; i < num; i++) {
76		mp_register_ioapic(i, pentry->phys_addr, gsi_top, &cfg);
77		pentry++;
78	}
79
80	WARN(pic_mode, KERN_WARNING
81		"SFI: pic_mod shouldn't be 1 when IOAPIC table is present\n");
82	pic_mode = 0;
83	return 0;
84}
85#endif /* CONFIG_X86_IO_APIC */
86
87/*
88 * sfi_platform_init(): register lapics & io-apics
89 */
90int __init sfi_platform_init(void)
91{
92#ifdef CONFIG_X86_LOCAL_APIC
93	register_lapic_address(sfi_lapic_addr);
94	sfi_table_parse(SFI_SIG_CPUS, NULL, NULL, sfi_parse_cpus);
95#endif
96#ifdef CONFIG_X86_IO_APIC
97	sfi_table_parse(SFI_SIG_APIC, NULL, NULL, sfi_parse_ioapic);
98#endif
99	return 0;
100}
101