4 #include <device/device.h>
5 #include <cpu/x86/lapic_def.h>
8 * Structure definitions for SMP machines following the
9 * Intel Multiprocessing Specification 1.1 and 1.4.
13 * This tag identifies where the SMP configuration
17 #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
20 * a maximum of 16 APICs with the current APIC ID architecture.
25 #define SMP_FLOATING_TABLE_LEN sizeof(struct intel_mp_floating)
27 struct intel_mp_floating
29 char mpf_signature[4]; /* "_MP_" */
30 unsigned long mpf_physptr; /* Configuration table address */
31 unsigned char mpf_length; /* Our length (paragraphs) */
32 unsigned char mpf_specification;/* Specification version */
33 unsigned char mpf_checksum; /* Checksum (makes sum 0) */
34 unsigned char mpf_feature1; /* Standard or configuration ? */
35 unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */
36 #define MP_FEATURE_VIRTUALWIRE (1 << 7)
37 #define MP_FEATURE_PIC (0 << 7)
38 unsigned char mpf_feature3; /* Unused (0) */
39 unsigned char mpf_feature4; /* Unused (0) */
40 unsigned char mpf_feature5; /* Unused (0) */
41 } __attribute__((packed));
43 struct mp_config_table
45 char mpc_signature[4];
46 #define MPC_SIGNATURE "PCMP"
47 unsigned short mpc_length; /* Size of table */
48 char mpc_spec; /* 0x01 */
51 char mpc_productid[12];
52 unsigned long mpc_oemptr; /* 0 if not present */
53 unsigned short mpc_oemsize; /* 0 if not present */
54 unsigned short mpc_entry_count;
55 unsigned long mpc_lapic; /* APIC address */
56 unsigned short mpe_length; /* Extended Table size */
57 unsigned char mpe_checksum; /* Extended Table checksum */
58 unsigned char reserved;
59 } __attribute__((packed));
61 /* Followed by entries */
63 #define MP_PROCESSOR 0
69 struct mpc_config_processor
71 unsigned char mpc_type;
72 unsigned char mpc_apicid; /* Local APIC number */
73 unsigned char mpc_apicver; /* Its versions */
74 unsigned char mpc_cpuflag;
75 #define MPC_CPU_ENABLED 1 /* Processor is available */
76 #define MPC_CPU_BOOTPROCESSOR 2 /* Processor is the BP */
77 unsigned long mpc_cpufeature;
78 #define MPC_CPU_STEPPING_MASK 0x0F
79 #define MPC_CPU_MODEL_MASK 0xF0
80 #define MPC_CPU_FAMILY_MASK 0xF00
81 unsigned long mpc_featureflag; /* CPUID feature value */
82 unsigned long mpc_reserved[2];
83 } __attribute__((packed));
87 unsigned char mpc_type;
88 unsigned char mpc_busid;
89 unsigned char mpc_bustype[6];
90 } __attribute__((packed));
92 #define BUSTYPE_EISA "EISA"
93 #define BUSTYPE_ISA "ISA"
94 #define BUSTYPE_INTERN "INTERN" /* Internal BUS */
95 #define BUSTYPE_MCA "MCA"
96 #define BUSTYPE_VL "VL" /* Local bus */
97 #define BUSTYPE_PCI "PCI"
98 #define BUSTYPE_PCMCIA "PCMCIA"
100 struct mpc_config_ioapic
102 unsigned char mpc_type;
103 unsigned char mpc_apicid;
104 unsigned char mpc_apicver;
105 unsigned char mpc_flags;
106 #define MPC_APIC_USABLE 0x01
107 unsigned long mpc_apicaddr;
108 } __attribute__((packed));
110 struct mpc_config_intsrc
112 unsigned char mpc_type;
113 unsigned char mpc_irqtype;
114 unsigned short mpc_irqflag;
115 unsigned char mpc_srcbus;
116 unsigned char mpc_srcbusirq;
117 unsigned char mpc_dstapic;
118 unsigned char mpc_dstirq;
119 } __attribute__((packed));
121 enum mp_irq_source_types {
128 #define MP_IRQ_POLARITY_DEFAULT 0x0
129 #define MP_IRQ_POLARITY_HIGH 0x1
130 #define MP_IRQ_POLARITY_LOW 0x3
131 #define MP_IRQ_POLARITY_MASK 0x3
132 #define MP_IRQ_TRIGGER_DEFAULT 0x0
133 #define MP_IRQ_TRIGGER_EDGE 0x4
134 #define MP_IRQ_TRIGGER_LEVEL 0xc
135 #define MP_IRQ_TRIGGER_MASK 0xc
138 struct mpc_config_lintsrc
140 unsigned char mpc_type;
141 unsigned char mpc_irqtype;
142 unsigned short mpc_irqflag;
143 unsigned char mpc_srcbusid;
144 unsigned char mpc_srcbusirq;
145 unsigned char mpc_destapic;
146 #define MP_APIC_ALL 0xFF
147 unsigned char mpc_destapiclint;
148 } __attribute__((packed));
151 * Default configurations
153 * 1 2 CPU ISA 82489DX
154 * 2 2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining
155 * 3 2 CPU EISA 82489DX
156 * 4 2 CPU MCA 82489DX
162 #define MAX_IRQ_SOURCES 128
163 #define MAX_MP_BUSSES 32
171 /* Followed by entries */
173 #define MPE_SYSTEM_ADDRESS_SPACE 0x80
174 #define MPE_BUS_HIERARCHY 0x81
175 #define MPE_COMPATIBILITY_ADDRESS_SPACE 0x82
177 struct mp_exten_config {
178 unsigned char mpe_type;
179 unsigned char mpe_length;
180 } __attribute__((packed));
182 typedef struct mp_exten_config *mpe_t;
184 struct mp_exten_system_address_space {
185 unsigned char mpe_type;
186 unsigned char mpe_length;
187 unsigned char mpe_busid;
188 unsigned char mpe_address_type;
189 #define ADDRESS_TYPE_IO 0
190 #define ADDRESS_TYPE_MEM 1
191 #define ADDRESS_TYPE_PREFETCH 2
192 unsigned int mpe_address_base_low;
193 unsigned int mpe_address_base_high;
194 unsigned int mpe_address_length_low;
195 unsigned int mpe_address_length_high;
196 } __attribute__((packed));
198 struct mp_exten_bus_hierarchy {
199 unsigned char mpe_type;
200 unsigned char mpe_length;
201 unsigned char mpe_busid;
202 unsigned char mpe_bus_info;
203 #define BUS_SUBTRACTIVE_DECODE 1
204 unsigned char mpe_parent_busid;
205 unsigned char reserved[3];
206 } __attribute__((packed));
208 struct mp_exten_compatibility_address_space {
209 unsigned char mpe_type;
210 unsigned char mpe_length;
211 unsigned char mpe_busid;
212 unsigned char mpe_address_modifier;
213 #define ADDRESS_RANGE_SUBTRACT 1
214 #define ADDRESS_RANGE_ADD 0
215 unsigned int mpe_range_list;
216 #define RANGE_LIST_IO_ISA 0
222 #define RANGE_LIST_IO_VGA 1
232 } __attribute__((packed));
234 void mptable_init(struct mp_config_table *mc, u32 lapic_addr);
236 void *smp_next_mpc_entry(struct mp_config_table *mc);
237 void *smp_next_mpe_entry(struct mp_config_table *mc);
239 void smp_write_processor(struct mp_config_table *mc,
240 unsigned char apicid, unsigned char apicver,
241 unsigned char cpuflag, unsigned int cpufeature,
242 unsigned int featureflag);
243 void smp_write_processors(struct mp_config_table *mc);
244 void smp_write_ioapic(struct mp_config_table *mc,
245 unsigned char id, unsigned char ver,
246 unsigned long apicaddr);
247 void smp_write_intsrc(struct mp_config_table *mc,
248 unsigned char irqtype, unsigned short irqflag,
249 unsigned char srcbus, unsigned char srcbusirq,
250 unsigned char dstapic, unsigned char dstirq);
251 void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
252 unsigned char irqtype, unsigned short irqflag,
254 unsigned char dstapic, unsigned char *dstirq);
255 void smp_write_lintsrc(struct mp_config_table *mc,
256 unsigned char irqtype, unsigned short irqflag,
257 unsigned char srcbusid, unsigned char srcbusirq,
258 unsigned char destapic, unsigned char destapiclint);
259 void smp_write_address_space(struct mp_config_table *mc,
260 unsigned char busid, unsigned char address_type,
261 unsigned int address_base_low, unsigned int address_base_high,
262 unsigned int address_length_low, unsigned int address_length_high);
263 void smp_write_bus_hierarchy(struct mp_config_table *mc,
264 unsigned char busid, unsigned char bus_info,
265 unsigned char parent_busid);
266 void smp_write_compatibility_address_space(struct mp_config_table *mc,
267 unsigned char busid, unsigned char address_modifier,
268 unsigned int range_list);
269 void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire);
270 unsigned long write_smp_table(unsigned long addr);
272 void mptable_lintsrc(struct mp_config_table *mc, unsigned long bus_isa);
273 void mptable_add_isa_interrupts(struct mp_config_table *mc, unsigned long bus_isa, unsigned long apicid, int external);
274 void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus, int *isa_bus);
275 void *mptable_finalize(struct mp_config_table *mc);