Subversion Repositories HelenOS-historic

Rev

Rev 21 | Rev 31 | Go to most recent revision | Show entire file | Ignore 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 181... Line 179...
181
    lo |= DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
179
    lo |= DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
182
    hi |= apicid << 24;
180
    hi |= apicid << 24;
183
   
181
   
184
    l_apic[ICRhi] = hi;
182
    l_apic[ICRhi] = hi;
185
    l_apic[ICRlo] = lo;
183
    l_apic[ICRlo] = lo;
186
   
184
 
187
    /*
185
    /*
188
     * According to MP Specification, 20us should be enough to
186
     * According to MP Specification, 20us should be enough to
189
     * deliver the IPI.
187
     * deliver the IPI.
190
     */
188
     */
191
    delay(20);
189
    delay(20);
Line 193... Line 191...
193
    if (!apic_poll_errors()) return 0;
191
    if (!apic_poll_errors()) return 0;
194
 
192
 
195
    lo = l_apic[ICRlo] & ICRloClear;
193
    lo = l_apic[ICRlo] & ICRloClear;
196
    if (lo & SEND_PENDING)
194
    if (lo & SEND_PENDING)
197
        printf("IPI is pending.\n");
195
        printf("IPI is pending.\n");
198
   
196
 
199
    l_apic[ICRlo] = lo | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
197
    l_apic[ICRlo] = lo | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
200
 
198
 
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);
-
 
213
        }
216
    }
214
    }
217
   
215
   
-
 
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
    /*