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