Subversion Repositories HelenOS-historic

Rev

Rev 514 | Rev 516 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 514 Rev 515
Line 62... Line 62...
62
 
62
 
63
__u32 apic_id_mask = 0;
63
__u32 apic_id_mask = 0;
64
 
64
 
65
static int apic_poll_errors(void);
65
static int apic_poll_errors(void);
66
 
66
 
-
 
67
#ifdef LAPIC_VERBOSE
67
static char *delmod_str[] = {
68
static char *delmod_str[] = {
68
    "Fixed",
69
    "Fixed",
69
    "Lowest Priority",
70
    "Lowest Priority",
70
    "SMI",
71
    "SMI",
71
    "Reserved",
72
    "Reserved",
Line 102... Line 103...
102
 
103
 
103
static char *intpol_str[] = {
104
static char *intpol_str[] = {
104
    "Polarity High",
105
    "Polarity High",
105
    "Polarity Low"
106
    "Polarity Low"
106
};
107
};
-
 
108
#endif /* LAPIC_VERBOSE */
107
 
109
 
108
/** Initialize APIC on BSP. */
110
/** Initialize APIC on BSP. */
109
void apic_init(void)
111
void apic_init(void)
110
{
112
{
111
    __u32 tmp, id, i;
113
    io_apic_id_t idreg;
-
 
114
    int i;
112
 
115
 
113
    trap_register(VECTOR_APIC_SPUR, apic_spurious);
116
    trap_register(VECTOR_APIC_SPUR, apic_spurious);
114
 
117
 
115
    enable_irqs_function = io_apic_enable_irqs;
118
    enable_irqs_function = io_apic_enable_irqs;
116
    disable_irqs_function = io_apic_disable_irqs;
119
    disable_irqs_function = io_apic_disable_irqs;
Line 121... Line 124...
121
     * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
124
     * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
122
     * Other interrupts will be forwarded to the lowest priority CPU.
125
     * Other interrupts will be forwarded to the lowest priority CPU.
123
     */
126
     */
124
    io_apic_disable_irqs(0xffff);
127
    io_apic_disable_irqs(0xffff);
125
    trap_register(VECTOR_CLK, l_apic_timer_interrupt);
128
    trap_register(VECTOR_CLK, l_apic_timer_interrupt);
126
    for (i=0; i<16; i++) {
129
    for (i = 0; i < IRQ_COUNT; i++) {
127
        int pin;
130
        int pin;
128
   
131
   
129
        if ((pin = smp_irq_to_pin(i)) != -1) {
132
        if ((pin = smp_irq_to_pin(i)) != -1) {
130
            io_apic_change_ioredtbl(pin, 0xff, IVT_IRQBASE+i, LOPRI);
133
            io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI);
131
        }
134
        }
132
    }
135
    }
133
   
136
   
134
 
-
 
135
    /*
137
    /*
136
     * Ensure that io_apic has unique ID.
138
     * Ensure that io_apic has unique ID.
137
     */
139
     */
138
    tmp = io_apic_read(IOAPICID);
140
    idreg.value = io_apic_read(IOAPICID);
139
    id = (tmp >> 24) & 0xf;
-
 
140
    if ((1<<id) & apic_id_mask) {
141
    if ((1<<idreg.apic_id) & apic_id_mask) {    /* see if IO APIC ID is used already */
141
        int i;
-
 
142
       
-
 
143
        for (i=0; i<15; i++) {
142
        for (i = 0; i < APIC_ID_COUNT; i++) {
144
            if (!((1<<i) & apic_id_mask)) {
143
            if (!((1<<i) & apic_id_mask)) {
-
 
144
                idreg.apic_id = i;
145
                io_apic_write(IOAPICID, (tmp & (~(0xf<<24))) | (i<<24));
145
                io_apic_write(IOAPICID, idreg.value);
146
                break;
146
                break;
147
            }
147
            }
148
        }
148
        }
149
    }
149
    }
150
 
150
 
151
    /*
151
    /*
152
     * Configure the BSP's lapic.
152
     * Configure the BSP's lapic.
153
     */
153
     */
154
    l_apic_init();
154
    l_apic_init();
-
 
155
 
155
    l_apic_debug();
156
    l_apic_debug();
156
}
157
}
157
 
158
 
158
/** APIC spurious interrupt handler.
159
/** APIC spurious interrupt handler.
159
 *
160
 *
Line 176... Line 177...
176
    esr_t esr;
177
    esr_t esr;
177
   
178
   
178
    esr.value = l_apic[ESR];
179
    esr.value = l_apic[ESR];
179
   
180
   
180
    if (esr.send_checksum_error)
181
    if (esr.send_checksum_error)
181
        printf("Send CS Error\n");
182
        printf("Send Checksum Error\n");
182
    if (esr.receive_checksum_error)
183
    if (esr.receive_checksum_error)
183
        printf("Receive CS Error\n");
184
        printf("Receive Checksum Error\n");
184
    if (esr.send_accept_error)
185
    if (esr.send_accept_error)
185
        printf("Send Accept Error\n");
186
        printf("Send Accept Error\n");
186
    if (esr.receive_accept_error)
187
    if (esr.receive_accept_error)
187
        printf("Receive Accept Error\n");
188
        printf("Receive Accept Error\n");
188
    if (esr.send_illegal_vector)
189
    if (esr.send_illegal_vector)
Line 214... Line 215...
214
    icr.vector = vector;
215
    icr.vector = vector;
215
 
216
 
216
    l_apic[ICRlo] = icr.lo;
217
    l_apic[ICRlo] = icr.lo;
217
 
218
 
218
    icr.lo = l_apic[ICRlo];
219
    icr.lo = l_apic[ICRlo];
219
    if (icr.lo & SEND_PENDING)
220
    if (icr.delivs == DELIVS_PENDING)
220
        printf("IPI is pending.\n");
221
        printf("IPI is pending.\n");
221
 
222
 
222
    return apic_poll_errors();
223
    return apic_poll_errors();
223
}
224
}
224
 
225
 
Line 257... Line 258...
257
    delay(20);
258
    delay(20);
258
 
259
 
259
    if (!apic_poll_errors()) return 0;
260
    if (!apic_poll_errors()) return 0;
260
 
261
 
261
    icr.lo = l_apic[ICRlo];
262
    icr.lo = l_apic[ICRlo];
262
    if (icr.lo & SEND_PENDING)
263
    if (icr.delivs == DELIVS_PENDING)
263
        printf("IPI is pending.\n");
264
        printf("IPI is pending.\n");
264
 
265
 
265
    icr.delmod = DELMOD_INIT;
266
    icr.delmod = DELMOD_INIT;
266
    icr.destmod = DESTMOD_PHYS;
267
    icr.destmod = DESTMOD_PHYS;
267
    icr.level = LEVEL_DEASSERT;
268
    icr.level = LEVEL_DEASSERT;
Line 290... Line 291...
290
            l_apic[ICRlo] = icr.lo;
291
            l_apic[ICRlo] = icr.lo;
291
            delay(200);
292
            delay(200);
292
        }
293
        }
293
    }
294
    }
294
   
295
   
295
   
-
 
296
    return apic_poll_errors();
296
    return apic_poll_errors();
297
}
297
}
298
 
298
 
299
/** Initialize Local APIC. */
299
/** Initialize Local APIC. */
300
void l_apic_init(void)
300
void l_apic_init(void)
Line 364... Line 364...
364
    t1 = l_apic[CCRT];
364
    t1 = l_apic[CCRT];
365
    delay(1000);
365
    delay(1000);
366
    t2 = l_apic[CCRT];
366
    t2 = l_apic[CCRT];
367
   
367
   
368
    l_apic[ICRT] = t1-t2;
368
    l_apic[ICRT] = t1-t2;
369
   
-
 
370
}
369
}
371
 
370
 
372
/** Local APIC End of Interrupt. */
371
/** Local APIC End of Interrupt. */
373
void l_apic_eoi(void)
372
void l_apic_eoi(void)
374
{
373
{
Line 411... Line 410...
411
 *
410
 *
412
 * @return Local APIC ID.
411
 * @return Local APIC ID.
413
 */
412
 */
414
__u8 l_apic_id(void)
413
__u8 l_apic_id(void)
415
{
414
{
416
    lapic_id_t lapic_id;
415
    l_apic_id_t idreg;
417
   
416
   
418
    lapic_id.value = l_apic[L_APIC_ID];
417
    idreg.value = l_apic[L_APIC_ID];
419
    return lapic_id.apic_id;
418
    return idreg.apic_id;
420
}
419
}
421
 
420
 
422
/** Read from IO APIC register.
421
/** Read from IO APIC register.
423
 *
422
 *
424
 * @param address IO APIC register address.
423
 * @param address IO APIC register address.
Line 488... Line 487...
488
{
487
{
489
    io_redirection_reg_t reg;
488
    io_redirection_reg_t reg;
490
    int i, pin;
489
    int i, pin;
491
   
490
   
492
    for (i=0;i<16;i++) {
491
    for (i=0;i<16;i++) {
493
        if ((irqmask>>i) & 1) {
492
        if (irqmask & (1<<i)) {
494
            /*
493
            /*
495
             * Mask the signal input in IO APIC if there is a
494
             * Mask the signal input in IO APIC if there is a
496
             * mapping for the respective IRQ number.
495
             * mapping for the respective IRQ number.
497
             */
496
             */
498
            pin = smp_irq_to_pin(i);
497
            pin = smp_irq_to_pin(i);
Line 514... Line 513...
514
{
513
{
515
    int i, pin;
514
    int i, pin;
516
    io_redirection_reg_t reg;  
515
    io_redirection_reg_t reg;  
517
   
516
   
518
    for (i=0;i<16;i++) {
517
    for (i=0;i<16;i++) {
519
        if ((irqmask>>i) & 1) {
518
        if (irqmask & (1<<i)) {
520
            /*
519
            /*
521
             * Unmask the signal input in IO APIC if there is a
520
             * Unmask the signal input in IO APIC if there is a
522
             * mapping for the respective IRQ number.
521
             * mapping for the respective IRQ number.
523
             */
522
             */
524
            pin = smp_irq_to_pin(i);
523
            pin = smp_irq_to_pin(i);
Line 528... Line 527...
528
                io_apic_write(IOREDTBL + pin*2, reg.lo);
527
                io_apic_write(IOREDTBL + pin*2, reg.lo);
529
            }
528
            }
530
           
529
           
531
        }
530
        }
532
    }
531
    }
533
 
-
 
534
}
532
}
535
 
533
 
536
#endif /* CONFIG_SMP */
534
#endif /* CONFIG_SMP */