Subversion Repositories HelenOS

Rev

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

Rev 1888 Rev 1970
Line 42... Line 42...
42
#include <interrupt.h>
42
#include <interrupt.h>
43
#include <arch/interrupt.h>
43
#include <arch/interrupt.h>
44
#include <print.h>
44
#include <print.h>
45
#include <arch/asm.h>
45
#include <arch/asm.h>
46
#include <arch.h>
46
#include <arch.h>
-
 
47
#include <ddi/irq.h>
-
 
48
#include <ddi/device.h>
47
 
49
 
48
#ifdef CONFIG_SMP
50
#ifdef CONFIG_SMP
49
 
51
 
50
/*
52
/*
51
 * Advanced Programmable Interrupt Controller for SMP systems.
53
 * Advanced Programmable Interrupt Controller for SMP systems.
Line 69... Line 71...
69
 */
71
 */
70
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
72
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
71
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000;
73
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000;
72
 
74
 
73
uint32_t apic_id_mask = 0;
75
uint32_t apic_id_mask = 0;
-
 
76
static irq_t l_apic_timer_irq;
74
 
77
 
75
static int apic_poll_errors(void);
78
static int apic_poll_errors(void);
76
 
79
 
77
#ifdef LAPIC_VERBOSE
80
#ifdef LAPIC_VERBOSE
78
static char *delmod_str[] = {
81
static char *delmod_str[] = {
Line 115... Line 118...
115
    "Polarity High",
118
    "Polarity High",
116
    "Polarity Low"
119
    "Polarity Low"
117
};
120
};
118
#endif /* LAPIC_VERBOSE */
121
#endif /* LAPIC_VERBOSE */
119
 
122
 
-
 
123
/** APIC spurious interrupt handler.
-
 
124
 *
-
 
125
 * @param n Interrupt vector.
-
 
126
 * @param istate Interrupted state.
-
 
127
 */
-
 
128
static void apic_spurious(int n, istate_t *istate)
-
 
129
{
-
 
130
#ifdef CONFIG_DEBUG
-
 
131
    printf("cpu%d: APIC spurious interrupt\n", CPU->id);
-
 
132
#endif
-
 
133
}
120
 
134
 
121
static void apic_spurious(int n, istate_t *istate);
135
static irq_ownership_t l_apic_timer_claim(void)
-
 
136
{
-
 
137
    return IRQ_ACCEPT;
-
 
138
}
-
 
139
 
122
static void l_apic_timer_interrupt(int n, istate_t *istate);
140
static void l_apic_timer_irq_handler(irq_t *irq, void *arg, ...)
-
 
141
{
-
 
142
    clock();
-
 
143
}
123
 
144
 
124
/** Initialize APIC on BSP. */
145
/** Initialize APIC on BSP. */
125
void apic_init(void)
146
void apic_init(void)
126
{
147
{
127
    io_apic_id_t idreg;
148
    io_apic_id_t idreg;
Line 137... Line 158...
137
     * Configure interrupt routing.
158
     * Configure interrupt routing.
138
     * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
159
     * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
139
     * Other interrupts will be forwarded to the lowest priority CPU.
160
     * Other interrupts will be forwarded to the lowest priority CPU.
140
     */
161
     */
141
    io_apic_disable_irqs(0xffff);
162
    io_apic_disable_irqs(0xffff);
-
 
163
   
-
 
164
    irq_initialize(&l_apic_timer_irq);
-
 
165
    l_apic_timer_irq.devno = device_assign_devno();
-
 
166
    l_apic_timer_irq.inr = IRQ_CLK;
-
 
167
    l_apic_timer_irq.claim = l_apic_timer_claim;
142
    exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt);
168
    l_apic_timer_irq.handler = l_apic_timer_irq_handler;
-
 
169
    irq_register(&l_apic_timer_irq);
-
 
170
   
143
    for (i = 0; i < IRQ_COUNT; i++) {
171
    for (i = 0; i < IRQ_COUNT; i++) {
144
        int pin;
172
        int pin;
145
   
173
   
146
        if ((pin = smp_irq_to_pin(i)) != -1) {
174
        if ((pin = smp_irq_to_pin(i)) != -1)
147
            io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI);
175
            io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI);
148
        }
-
 
149
    }
176
    }
150
   
177
   
151
    /*
178
    /*
152
     * Ensure that io_apic has unique ID.
179
     * Ensure that io_apic has unique ID.
153
     */
180
     */
154
    idreg.value = io_apic_read(IOAPICID);
181
    idreg.value = io_apic_read(IOAPICID);
155
    if ((1<<idreg.apic_id) & apic_id_mask) {    /* see if IO APIC ID is used already */
182
    if ((1 << idreg.apic_id) & apic_id_mask) {  /* see if IO APIC ID is used already */
156
        for (i = 0; i < APIC_ID_COUNT; i++) {
183
        for (i = 0; i < APIC_ID_COUNT; i++) {
157
            if (!((1<<i) & apic_id_mask)) {
184
            if (!((1 << i) & apic_id_mask)) {
158
                idreg.apic_id = i;
185
                idreg.apic_id = i;
159
                io_apic_write(IOAPICID, idreg.value);
186
                io_apic_write(IOAPICID, idreg.value);
160
                break;
187
                break;
161
            }
188
            }
162
        }
189
        }
Line 168... Line 195...
168
    l_apic_init();
195
    l_apic_init();
169
 
196
 
170
    l_apic_debug();
197
    l_apic_debug();
171
}
198
}
172
 
199
 
173
/** APIC spurious interrupt handler.
-
 
174
 *
-
 
175
 * @param n Interrupt vector.
-
 
176
 * @param istate Interrupted state.
-
 
177
 */
-
 
178
void apic_spurious(int n, istate_t *istate)
-
 
179
{
-
 
180
#ifdef CONFIG_DEBUG
-
 
181
    printf("cpu%d: APIC spurious interrupt\n", CPU->id);
-
 
182
#endif
-
 
183
}
-
 
184
 
-
 
185
/** Poll for APIC errors.
200
/** Poll for APIC errors.
186
 *
201
 *
187
 * Examine Error Status Register and report all errors found.
202
 * Examine Error Status Register and report all errors found.
188
 *
203
 *
189
 * @return 0 on error, 1 on success.
204
 * @return 0 on error, 1 on success.
Line 438... Line 453...
438
    error.value = l_apic[LVT_Err];
453
    error.value = l_apic[LVT_Err];
439
    printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
454
    printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
440
#endif
455
#endif
441
}
456
}
442
 
457
 
443
/** Local APIC Timer Interrupt.
-
 
444
 *
-
 
445
 * @param n Interrupt vector number.
-
 
446
 * @param istate Interrupted state.
-
 
447
 */
-
 
448
void l_apic_timer_interrupt(int n, istate_t *istate)
-
 
449
{
-
 
450
    l_apic_eoi();
-
 
451
    clock();
-
 
452
}
-
 
453
 
-
 
454
/** Get Local APIC ID.
458
/** Get Local APIC ID.
455
 *
459
 *
456
 * @return Local APIC ID.
460
 * @return Local APIC ID.
457
 */
461
 */
458
uint8_t l_apic_id(void)
462
uint8_t l_apic_id(void)