Rev 21 | Rev 31 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 21 | Rev 27 | ||
---|---|---|---|
Line 101... | Line 101... | ||
101 | break; |
101 | break; |
102 | } |
102 | } |
103 | } |
103 | } |
104 | } |
104 | } |
105 | 105 | ||
106 | - | ||
107 | - | ||
108 | /* |
106 | /* |
109 | * Configure the BSP's lapic. |
107 | * Configure the BSP's lapic. |
110 | */ |
108 | */ |
111 | l_apic_init(); |
109 | l_apic_init(); |
112 | l_apic_debug(); |
110 | l_apic_debug(); |
Line 201... | Line 199... | ||
201 | /* |
199 | /* |
202 | * Wait 10ms as MP Specification specifies. |
200 | * Wait 10ms as MP Specification specifies. |
203 | */ |
201 | */ |
204 | delay(10000); |
202 | delay(10000); |
205 | 203 | ||
- | 204 | if (!is_82489DX_apic(l_apic[LAVR])) { |
|
206 | /* |
205 | /* |
207 | * MP specification says this should not be done for 82489DX-based |
- | |
208 | * l_apic's. However, everything is ok as long as STARTUP IPI is ignored |
206 | * If this is not 82489DX-based l_apic we must send two STARTUP IPI's. |
209 | * by 8249DX. |
- | |
210 | */ |
207 | */ |
211 | for (i = 0; i < 2; i++) { |
208 | for (i = 0; i<2; i++) { |
212 | lo = l_apic[ICRlo] & ICRloClear; |
209 | lo = l_apic[ICRlo] & ICRloClear; |
213 | lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */ |
210 | lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */ |
214 | l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL; |
211 | l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL; |
215 | delay(200); |
212 | delay(200); |
216 | } |
213 | } |
- | 214 | } |
|
- | 215 | ||
217 | 216 | ||
218 | return apic_poll_errors(); |
217 | return apic_poll_errors(); |
219 | } |
218 | } |
220 | 219 | ||
221 | void l_apic_init(void) |
220 | void l_apic_init(void) |
222 | { |
221 | { |
223 | __u32 tmp, t1, t2; |
222 | __u32 tmp, t1, t2; |
224 | int cpu_id = config.cpu_active - 1; |
- | |
225 | - | ||
226 | - | ||
227 | /* |
- | |
228 | * Here we set local APIC ID's so that they match operating system's CPU ID's |
- | |
229 | * This operation is dangerous as it is model specific. |
- | |
230 | * TODO: some care should be taken. |
- | |
231 | * NOTE: CPU may not be used to define APIC ID |
- | |
232 | */ |
- | |
233 | if (l_apic_id() != cpu_id) { |
- | |
234 | l_apic[L_APIC_ID] &= L_APIC_IDClear; |
- | |
235 | l_apic[L_APIC_ID] |= (l_apic[L_APIC_ID]&L_APIC_IDClear)|((cpu_id)<<L_APIC_IDShift); |
- | |
236 | } |
- | |
237 | 223 | ||
238 | l_apic[LVT_Err] |= (1<<16); |
224 | l_apic[LVT_Err] |= (1<<16); |
239 | l_apic[LVT_LINT0] |= (1<<16); |
225 | l_apic[LVT_LINT0] |= (1<<16); |
240 | l_apic[LVT_LINT1] |= (1<<16); |
226 | l_apic[LVT_LINT1] |= (1<<16); |
241 | 227 | ||
242 | tmp = l_apic[SVR] & SVRClear; |
228 | tmp = l_apic[SVR] & SVRClear; |
243 | l_apic[SVR] = tmp | (1<<8) | (VECTOR_APIC_SPUR); |
229 | l_apic[SVR] = tmp | (1<<8) | (VECTOR_APIC_SPUR); |
244 | 230 | ||
245 | l_apic[TPR] &= TPRClear; |
231 | l_apic[TPR] &= TPRClear; |
246 | 232 | ||
247 | if (CPU->arch.family >= 6) |
233 | // if (CPU->arch.family >= 6) |
248 | enable_l_apic_in_msr(); |
234 | // enable_l_apic_in_msr(); |
249 | 235 | ||
250 | tmp = l_apic[ICRlo] & ICRloClear; |
236 | tmp = l_apic[ICRlo] & ICRloClear; |
251 | l_apic[ICRlo] = tmp | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_INCL | TRGRMODE_LEVEL; |
237 | l_apic[ICRlo] = tmp | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_INCL | TRGRMODE_LEVEL; |
252 | 238 | ||
253 | /* |
239 | /* |