1 | /*␊ |
2 | * <Insert copyright here : it must be BSD-like so everyone can use it>␊ |
3 | *␊ |
4 | * Author: Erich Boleyn <erich@uruk.org> http://www.uruk.org/~erich/␊ |
5 | *␊ |
6 | * Header file implementing Intel MultiProcessor Specification (MPS)␊ |
7 | * version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs,␊ |
8 | * with hooks for running correctly on a standard PC without the hardware.␊ |
9 | *␊ |
10 | * This file was created from information in the Intel MPS version 1.4␊ |
11 | * document, order number 242016-004, which can be ordered from the␊ |
12 | * Intel literature center.␊ |
13 | */␊ |
14 | ␊ |
15 | #ifndef _SMP_IMPS_H␊ |
16 | #define _SMP_IMPS_H␊ |
17 | #include "apic.h"␊ |
18 | /* make sure "apic.h" is included */␊ |
19 | #ifndef _APIC_H␊ |
20 | #error␉␉Must include "apic.h" before "smp-imps.h"␊ |
21 | #endif /* !_APIC_H */␊ |
22 | ␊ |
23 | ␊ |
24 | /*␊ |
25 | * Defines used.␊ |
26 | */␊ |
27 | ␊ |
28 | #define IMPS_READ(x)␉(*((volatile unsigned *) (x)))␊ |
29 | #define IMPS_WRITE(x,y)␉(*((volatile unsigned *) (x)) = (y))␊ |
30 | ␊ |
31 | #ifdef IMPS_DEBUG␊ |
32 | #define IMPS_DEBUG_PRINT(x) KERNEL_PRINT(x)␊ |
33 | #else /* !IMPS_DEBUG */␊ |
34 | #define IMPS_DEBUG_PRINT(x)␊ |
35 | #endif /* !IMPS_DEBUG */␊ |
36 | ␊ |
37 | #define IMPS_MAX_CPUS␉␉␉APIC_BCAST_ID␊ |
38 | ␊ |
39 | /*␊ |
40 | * This is the value that must be in the "sig" member of the MP␊ |
41 | * Floating Pointer Structure.␊ |
42 | */␊ |
43 | #define IMPS_FPS_SIGNATURE␉('_' | ('M'<<8) | ('P'<<16) | ('_'<<24))␊ |
44 | #define IMPS_FPS_IMCRP_BIT␉0x80␊ |
45 | #define IMPS_FPS_DEFAULT_MAX␉7␊ |
46 | ␊ |
47 | /*␊ |
48 | * This is the value that must be in the "sig" member of the MP␊ |
49 | * Configuration Table Header.␊ |
50 | */␊ |
51 | #define IMPS_CTH_SIGNATURE␉('P' | ('C'<<8) | ('M'<<16) | ('P'<<24))␊ |
52 | ␊ |
53 | /*␊ |
54 | * These are the "type" values for Base MP Configuration Table entries.␊ |
55 | */␊ |
56 | #define␉␉IMPS_FLAG_ENABLED␉1␊ |
57 | #define IMPS_BCT_PROCESSOR␉␉0␊ |
58 | #define␉␉IMPS_CPUFLAG_BOOT␉2␊ |
59 | #define IMPS_BCT_BUS␉␉␉1␊ |
60 | #define IMPS_BCT_IOAPIC␉␉␉2␊ |
61 | #define IMPS_BCT_IO_INTERRUPT␉␉3␊ |
62 | #define IMPS_BCT_LOCAL_INTERRUPT␉4␊ |
63 | #define␉␉IMPS_INT_INT␉␉0␊ |
64 | #define␉␉IMPS_INT_NMI␉␉1␊ |
65 | #define␉␉IMPS_INT_SMI␉␉2␊ |
66 | #define␉␉IMPS_INT_EXTINT␉␉3␊ |
67 | ␊ |
68 | ␊ |
69 | /*␊ |
70 | * Typedefs and data item definitions done here.␊ |
71 | */␊ |
72 | ␊ |
73 | typedef struct imps_fps imps_fps;␉/* MP floating pointer structure */␊ |
74 | typedef struct imps_cth imps_cth;␉/* MP configuration table header */␊ |
75 | typedef struct imps_processor imps_processor;␊ |
76 | typedef struct imps_bus imps_bus;␊ |
77 | typedef struct imps_ioapic imps_ioapic;␊ |
78 | typedef struct imps_interrupt imps_interrupt;␊ |
79 | ␊ |
80 | ␊ |
81 | /*␊ |
82 | * Data structures defined here␊ |
83 | */␊ |
84 | ␊ |
85 | /*␊ |
86 | * MP Floating Pointer Structure (fps)␊ |
87 | *␊ |
88 | * Look at page 4-3 of the MP spec for the starting definitions of␊ |
89 | * this structure.␊ |
90 | */␊ |
91 | struct imps_fps␊ |
92 | {␊ |
93 | ␉unsigned sig;␊ |
94 | ␉imps_cth *cth_ptr;␊ |
95 | ␉unsigned char length;␊ |
96 | ␉unsigned char spec_rev;␊ |
97 | ␉unsigned char checksum;␊ |
98 | ␉unsigned char feature_info[5];␊ |
99 | };␊ |
100 | ␊ |
101 | /*␊ |
102 | * MP Configuration Table Header (cth)␊ |
103 | *␊ |
104 | * Look at page 4-5 of the MP spec for the starting definitions of␊ |
105 | * this structure.␊ |
106 | */␊ |
107 | struct imps_cth␊ |
108 | {␊ |
109 | ␉unsigned sig;␊ |
110 | ␉unsigned short base_length;␊ |
111 | ␉unsigned char spec_rev;␊ |
112 | ␉unsigned char checksum;␊ |
113 | ␉char oem_id[8];␊ |
114 | ␉char prod_id[12];␊ |
115 | ␉unsigned oem_table_ptr;␊ |
116 | ␉unsigned short oem_table_size;␊ |
117 | ␉unsigned short entry_count;␊ |
118 | ␉unsigned lapic_addr;␊ |
119 | ␉unsigned short extended_length;␊ |
120 | ␉unsigned char extended_checksum;␊ |
121 | ␉char reserved[1];␊ |
122 | };␊ |
123 | ␊ |
124 | /*␊ |
125 | * Base MP Configuration Table Types. They are sorted according to␊ |
126 | * type (i.e. all of type 0 come first, etc.). Look on page 4-6 for␊ |
127 | * the start of the descriptions.␊ |
128 | */␊ |
129 | ␊ |
130 | struct imps_processor␊ |
131 | {␊ |
132 | ␉unsigned char type;␉␉␉/* must be 0 */␊ |
133 | ␉unsigned char apic_id;␊ |
134 | ␉unsigned char apic_ver;␊ |
135 | ␉unsigned char flags;␊ |
136 | ␉unsigned signature;␊ |
137 | ␉unsigned features;␊ |
138 | ␉char reserved[8];␊ |
139 | };␊ |
140 | ␊ |
141 | struct imps_bus␊ |
142 | {␊ |
143 | ␉unsigned char type;␉␉␉/* must be 1 */␊ |
144 | ␉unsigned char id;␊ |
145 | ␉char bus_type[6];␊ |
146 | };␊ |
147 | ␊ |
148 | struct imps_ioapic␊ |
149 | {␊ |
150 | ␉unsigned char type;␉␉␉/* must be 2 */␊ |
151 | ␉unsigned char id;␊ |
152 | ␉unsigned char ver;␊ |
153 | ␉unsigned char flags;␊ |
154 | ␉unsigned addr;␊ |
155 | };␊ |
156 | ␊ |
157 | struct imps_interrupt␊ |
158 | {␊ |
159 | ␉unsigned char type;␉␉␉/* must be 3 or 4 */␊ |
160 | ␉unsigned char int_type;␊ |
161 | ␉unsigned short flags;␊ |
162 | ␉unsigned char source_bus_id;␊ |
163 | ␉unsigned char source_bus_irq;␊ |
164 | ␉unsigned char dest_apic_id;␊ |
165 | ␉unsigned char dest_apic_intin;␊ |
166 | };␊ |
167 | ␊ |
168 | /*␊ |
169 | * Exported globals here.␊ |
170 | */␊ |
171 | ␊ |
172 | /*␊ |
173 | * "imps_enabled" is non-zero if the probe sequence found IMPS␊ |
174 | * information and was successful.␊ |
175 | */␊ |
176 | extern int imps_enabled;␊ |
177 | ␊ |
178 | /*␊ |
179 | * This contains the local APIC hardware address.␊ |
180 | */␊ |
181 | extern unsigned imps_lapic_addr;␊ |
182 | ␊ |
183 | /*␊ |
184 | * This represents the number of CPUs found.␊ |
185 | */␊ |
186 | extern int imps_num_cpus;␊ |
187 | ␊ |
188 | /*␊ |
189 | * These map from virtual cpu numbers to APIC id's and back.␊ |
190 | */␊ |
191 | extern unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS];␊ |
192 | extern unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];␊ |
193 | ␊ |
194 | /*␊ |
195 | * This is the primary function for probing for Intel MPS 1.1/1.4␊ |
196 | * compatible hardware and BIOS information. While probing the CPUs␊ |
197 | * information returned from the BIOS, this also starts up each CPU␊ |
198 | * and gets it ready for use.␊ |
199 | *␊ |
200 | * Call this during the early stages of OS startup, before memory can␊ |
201 | * be messed up.␊ |
202 | *␊ |
203 | * Returns N if IMPS information was found (for number of CPUs started)␊ |
204 | * and is valid, else 0.␊ |
205 | */␊ |
206 | ␊ |
207 | void *␊ |
208 | imps_probe(int * num_cpus);␊ |
209 | ␊ |
210 | /*␊ |
211 | * This one is used as a "force" function. Give it the number of CPUs␊ |
212 | * to start, and it will assume a certain number and try it.␊ |
213 | */␊ |
214 | ␊ |
215 | int imps_force(int ncpus);␊ |
216 | ␊ |
217 | /*␊ |
218 | * Defines that use variables␊ |
219 | */␊ |
220 | ␊ |
221 | #define IMPS_LAPIC_READ(x) (*((volatile unsigned *) (imps_lapic_addr+(x))))␊ |
222 | #define IMPS_LAPIC_WRITE(x, y) \␊ |
223 | (*((volatile unsigned *) (imps_lapic_addr+(x))) = (y))␊ |
224 | ␊ |
225 | #endif /* !_SMP_IMPS_H */␊ |
226 | |