xref: /aosp_15_r20/external/coreboot/src/arch/x86/include/arch/smp/mpspec.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __ASM_MPSPEC_H
4 #define __ASM_MPSPEC_H
5 
6 #include <acpi/acpi.h>
7 #include <device/device.h>
8 #include <cpu/x86/lapic_def.h>
9 #include <types.h>
10 
11 /*
12  * Structure definitions for SMP machines following the
13  * Intel Multiprocessing Specification 1.1 and 1.4.
14  */
15 
16 /*
17  * This tag identifies where the SMP configuration
18  * information is.
19  */
20 
21 #define SMP_MAGIC_IDENT	(('_'<<24)|('P'<<16)|('M'<<8)|'_')
22 
23 /*
24  * a maximum of 16 APICs with the current APIC ID architecture.
25  */
26 #define MAX_APICS 16
27 
28 #define SMP_FLOATING_TABLE_LEN sizeof(struct intel_mp_floating)
29 
30 struct intel_mp_floating {
31 	char mpf_signature[4];	/* "_MP_" */
32 	u32 mpf_physptr;	/* Configuration table address */
33 	u8 mpf_length;	/* Our length (paragraphs) */
34 	u8 mpf_specification;/* Specification version */
35 	u8 mpf_checksum;	/* Checksum (makes sum 0) */
36 	u8 mpf_feature1;	/* Predefined or Unique configuration? */
37 	u8 mpf_feature2;	/* Bit7 set for IMCR/PIC */
38 #define MP_FEATURE_VIRTUALWIRE (0 << 7)
39 #define MP_FEATURE_PIC         (1 << 7)
40 	u8 mpf_feature3;	/* Unused (0) */
41 	u8 mpf_feature4;	/* Unused (0) */
42 	u8 mpf_feature5;	/* Unused (0) */
43 } __packed;
44 
45 struct mp_config_table {
46 	char mpc_signature[4];
47 #define MPC_SIGNATURE "PCMP"
48 	u16 mpc_length;	/* Size of table */
49 	u8 mpc_spec;			/* 0x01 */
50 	u8 mpc_checksum;
51 	char  mpc_oem[8];
52 	char  mpc_productid[12];
53 	u32 mpc_oemptr;	/* 0 if not present */
54 	u16 mpc_oemsize;	/* 0 if not present */
55 	u16 mpc_entry_count;
56 	u32 mpc_lapic;	/* APIC address */
57 	u16 mpe_length;	/* Extended Table size */
58 	u8 mpe_checksum;	/* Extended Table checksum */
59 	u8 reserved;
60 } __packed;
61 
62 /* Followed by entries */
63 
64 #define	MP_PROCESSOR	0
65 #define	MP_BUS		1
66 #define	MP_IOAPIC	2
67 #define	MP_INTSRC	3
68 #define	MP_LINTSRC	4
69 
70 struct mpc_config_processor {
71 	u8 mpc_type;
72 	u8 mpc_apicid;	/* Local APIC number */
73 	u8 mpc_apicver;	/* Its versions */
74 	u8 mpc_cpuflag;
75 #define MPC_CPU_ENABLED		1	/* Processor is available */
76 #define MPC_CPU_BOOTPROCESSOR	2	/* Processor is the BP */
77 	u32 mpc_cpufeature;
78 #define MPC_CPU_STEPPING_MASK 0x0F
79 #define MPC_CPU_MODEL_MASK	0xF0
80 #define MPC_CPU_FAMILY_MASK	0xF00
81 	u32 mpc_featureflag;	/* CPUID feature value */
82 	u32 mpc_reserved[2];
83 } __packed;
84 
85 struct mpc_config_bus {
86 	u8 mpc_type;
87 	u8 mpc_busid;
88 	u8 mpc_bustype[6];
89 } __packed;
90 
91 #define BUSTYPE_EISA	"EISA"
92 #define BUSTYPE_ISA	"ISA"
93 #define BUSTYPE_INTERN	"INTERN"	/* Internal BUS */
94 #define BUSTYPE_MCA	"MCA"
95 #define BUSTYPE_VL	"VL"		/* Local bus */
96 #define BUSTYPE_PCI	"PCI"
97 #define BUSTYPE_PCMCIA	"PCMCIA"
98 
99 struct mpc_config_ioapic {
100 	u8 mpc_type;
101 	u8 mpc_apicid;
102 	u8 mpc_apicver;
103 	u8 mpc_flags;
104 #define MPC_APIC_USABLE		0x01
105 	uintptr_t mpc_apicaddr;
106 } __packed;
107 
108 struct mpc_config_intsrc {
109 	u8 mpc_type;
110 	u8 mpc_irqtype;
111 	u16 mpc_irqflag;
112 	u8 mpc_srcbus;
113 	u8 mpc_srcbusirq;
114 	u8 mpc_dstapic;
115 	u8 mpc_dstirq;
116 } __packed;
117 
118 enum mp_irq_source_types {
119 	mp_INT = 0,
120 	mp_NMI = 1,
121 	mp_SMI = 2,
122 	mp_ExtINT = 3
123 };
124 
125 struct mpc_config_lintsrc {
126 	u8 mpc_type;
127 	u8 mpc_irqtype;
128 	u16 mpc_irqflag;
129 	u8 mpc_srcbusid;
130 	u8 mpc_srcbusirq;
131 	u8 mpc_destapic;
132 #define MP_APIC_ALL	0xFF
133 	u8 mpc_destapiclint;
134 } __packed;
135 
136 /*
137  *	Default configurations
138  *
139  *	1	2 CPU ISA 82489DX
140  *	2	2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining
141  *	3	2 CPU EISA 82489DX
142  *	4	2 CPU MCA 82489DX
143  *	5	2 CPU ISA+PCI
144  *	6	2 CPU EISA+PCI
145  *	7	2 CPU MCA+PCI
146  */
147 
148 #define MAX_IRQ_SOURCES 128
149 #define MAX_MP_BUSSES 32
150 enum mp_bustype {
151 	MP_BUS_ISA = 0,
152 	MP_BUS_EISA,
153 	MP_BUS_PCI,
154 	MP_BUS_MCA
155 };
156 
157 /* Followed by entries */
158 
159 #define	MPE_SYSTEM_ADDRESS_SPACE	0x80
160 #define	MPE_BUS_HIERARCHY		0x81
161 #define	MPE_COMPATIBILITY_ADDRESS_SPACE	0x82
162 
163 struct mp_exten_config {
164 	u8 mpe_type;
165 	u8 mpe_length;
166 } __packed;
167 
168 typedef struct mp_exten_config *mpe_t;
169 
170 struct mp_exten_system_address_space {
171 	u8 mpe_type;
172 	u8 mpe_length;
173 	u8 mpe_busid;
174 	u8 mpe_address_type;
175 #define ADDRESS_TYPE_IO       0
176 #define ADDRESS_TYPE_MEM      1
177 #define ADDRESS_TYPE_PREFETCH 2
178 	u32 mpe_address_base_low;
179 	u32 mpe_address_base_high;
180 	u32 mpe_address_length_low;
181 	u32 mpe_address_length_high;
182 } __packed;
183 
184 struct mp_exten_bus_hierarchy {
185 	u8 mpe_type;
186 	u8 mpe_length;
187 	u8 mpe_busid;
188 	u8 mpe_bus_info;
189 #define BUS_SUBTRACTIVE_DECODE 1
190 	u8 mpe_parent_busid;
191 	u8 reserved[3];
192 } __packed;
193 
194 struct mp_exten_compatibility_address_space {
195 	u8 mpe_type;
196 	u8 mpe_length;
197 	u8 mpe_busid;
198 	u8 mpe_address_modifier;
199 #define ADDRESS_RANGE_SUBTRACT 1
200 #define ADDRESS_RANGE_ADD      0
201 	u32 mpe_range_list;
202 #define RANGE_LIST_IO_ISA	0
203 	/* X100 - X3FF
204 	 * X500 - X7FF
205 	 * X900 - XBFF
206 	 * XD00 - XFFF
207 	 */
208 #define RANGE_LIST_IO_VGA	1
209 	/* X3B0 - X3BB
210 	 * X3C0 - X3DF
211 	 * X7B0 - X7BB
212 	 * X7C0 - X7DF
213 	 * XBB0 - XBBB
214 	 * XBC0 - XBDF
215 	 * XFB0 - XFBB
216 	 * XFC0 - XCDF
217 	 */
218 } __packed;
219 
220 void mptable_init(struct mp_config_table *mc);
221 void *smp_next_mpc_entry(struct mp_config_table *mc);
222 void *smp_next_mpe_entry(struct mp_config_table *mc);
223 
224 void smp_write_processor(struct mp_config_table *mc,
225 	u8 apicid, u8 apicver,
226 	u8 cpuflag, u32 cpufeature,
227 	u32 featureflag);
228 void smp_write_processors(struct mp_config_table *mc);
229 
230 /* Call smp_write_ioapic() and return IOAPIC ID field. */
231 u8 smp_write_ioapic_from_hw(struct mp_config_table *mc, uintptr_t apicaddr);
232 
233 void smp_write_intsrc(struct mp_config_table *mc,
234 	u8 irqtype, u16 irqflag, u8 srcbus, u8 srcbusirq,
235 	u8 dstapic, u8 dstirq);
236 void smp_write_pci_intsrc(struct mp_config_table *mc,
237 	u8 irqtype, u8 srcbus, u8 dev, u8 pirq,
238 	u8 dstapic, u8 dstirq);
239 void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
240 	u8 irqtype, u16 irqflag,
241 	struct device *dev,
242 	unsigned char dstapic, unsigned char *dstirq);
243 void smp_write_lintsrc(struct mp_config_table *mc,
244 	u8 irqtype, u16 irqflag,
245 	u8 srcbusid, u8 srcbusirq,
246 	u8 destapic, u8 destapiclint);
247 void smp_write_address_space(struct mp_config_table *mc,
248 	u8 busid, u8 address_type,
249 	u32 address_base_low, u32 address_base_high,
250 	u32 address_length_low, u32 address_length_high);
251 void smp_write_bus_hierarchy(struct mp_config_table *mc,
252 	u8 busid, u8 bus_info,
253 	u8 parent_busid);
254 void smp_write_compatibility_address_space(struct mp_config_table *mc,
255 	u8 busid, u8 address_modifier,
256 	u32 range_list);
257 void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire);
258 unsigned long write_smp_table(unsigned long addr);
259 
260 void mptable_lintsrc(struct mp_config_table *mc, unsigned long bus_isa);
261 void mptable_add_isa_interrupts(struct mp_config_table *mc,
262 	unsigned long bus_isa, unsigned long apicid, int external);
263 void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus,
264 	int *isa_bus);
265 void *mptable_finalize(struct mp_config_table *mc);
266 
267 #endif
268