Subversion Repositories HelenOS-historic

Rev

Rev 1576 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1576 Rev 1702
1
/*
1
/*
2
 * Copyright (C) 2001-2005 Jakub Jermar
2
 * Copyright (C) 2001-2005 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
-
 
29
 /** @addtogroup ia32  
-
 
30
 * @{
-
 
31
 */
-
 
32
/** @file
-
 
33
 */
-
 
34
 
29
#ifdef CONFIG_SMP
35
#ifdef CONFIG_SMP
30
 
36
 
31
#include <config.h>
37
#include <config.h>
32
#include <print.h>
38
#include <print.h>
33
#include <debug.h>
39
#include <debug.h>
34
#include <arch/smp/mps.h>
40
#include <arch/smp/mps.h>
35
#include <arch/smp/apic.h>
41
#include <arch/smp/apic.h>
36
#include <arch/smp/smp.h>
42
#include <arch/smp/smp.h>
37
#include <func.h>
43
#include <func.h>
38
#include <arch/types.h>
44
#include <arch/types.h>
39
#include <typedefs.h>
45
#include <typedefs.h>
40
#include <cpu.h>
46
#include <cpu.h>
41
#include <arch/asm.h>
47
#include <arch/asm.h>
42
#include <arch/bios/bios.h>
48
#include <arch/bios/bios.h>
43
#include <mm/frame.h>
49
#include <mm/frame.h>
44
 
50
 
45
/*
51
/*
46
 * MultiProcessor Specification detection code.
52
 * MultiProcessor Specification detection code.
47
 */
53
 */
48
 
54
 
49
#define FS_SIGNATURE    0x5f504d5f
55
#define FS_SIGNATURE    0x5f504d5f
50
#define CT_SIGNATURE    0x504d4350
56
#define CT_SIGNATURE    0x504d4350
51
 
57
 
52
int mps_fs_check(__u8 *base);
58
int mps_fs_check(__u8 *base);
53
int mps_ct_check(void);
59
int mps_ct_check(void);
54
 
60
 
55
int configure_via_ct(void);
61
int configure_via_ct(void);
56
int configure_via_default(__u8 n);
62
int configure_via_default(__u8 n);
57
 
63
 
58
int ct_processor_entry(struct __processor_entry *pr);
64
int ct_processor_entry(struct __processor_entry *pr);
59
void ct_bus_entry(struct __bus_entry *bus);
65
void ct_bus_entry(struct __bus_entry *bus);
60
void ct_io_apic_entry(struct __io_apic_entry *ioa);
66
void ct_io_apic_entry(struct __io_apic_entry *ioa);
61
void ct_io_intr_entry(struct __io_intr_entry *iointr);
67
void ct_io_intr_entry(struct __io_intr_entry *iointr);
62
void ct_l_intr_entry(struct __l_intr_entry *lintr);
68
void ct_l_intr_entry(struct __l_intr_entry *lintr);
63
 
69
 
64
void ct_extended_entries(void);
70
void ct_extended_entries(void);
65
 
71
 
66
static struct mps_fs *fs;
72
static struct mps_fs *fs;
67
static struct mps_ct *ct;
73
static struct mps_ct *ct;
68
 
74
 
69
struct __processor_entry *processor_entries = NULL;
75
struct __processor_entry *processor_entries = NULL;
70
struct __bus_entry *bus_entries = NULL;
76
struct __bus_entry *bus_entries = NULL;
71
struct __io_apic_entry *io_apic_entries = NULL;
77
struct __io_apic_entry *io_apic_entries = NULL;
72
struct __io_intr_entry *io_intr_entries = NULL;
78
struct __io_intr_entry *io_intr_entries = NULL;
73
struct __l_intr_entry *l_intr_entries = NULL;
79
struct __l_intr_entry *l_intr_entries = NULL;
74
 
80
 
75
int processor_entry_cnt = 0;
81
int processor_entry_cnt = 0;
76
int bus_entry_cnt = 0;
82
int bus_entry_cnt = 0;
77
int io_apic_entry_cnt = 0;
83
int io_apic_entry_cnt = 0;
78
int io_intr_entry_cnt = 0;
84
int io_intr_entry_cnt = 0;
79
int l_intr_entry_cnt = 0;
85
int l_intr_entry_cnt = 0;
80
 
86
 
81
waitq_t ap_completion_wq;
87
waitq_t ap_completion_wq;
82
 
88
 
83
/*
89
/*
84
 * Implementation of IA-32 SMP configuration interface.
90
 * Implementation of IA-32 SMP configuration interface.
85
 */
91
 */
86
static count_t get_cpu_count(void);
92
static count_t get_cpu_count(void);
87
static bool is_cpu_enabled(index_t i);
93
static bool is_cpu_enabled(index_t i);
88
static bool is_bsp(index_t i);
94
static bool is_bsp(index_t i);
89
static __u8 get_cpu_apic_id(index_t i);
95
static __u8 get_cpu_apic_id(index_t i);
90
static int mps_irq_to_pin(int irq);
96
static int mps_irq_to_pin(int irq);
91
 
97
 
92
struct smp_config_operations mps_config_operations = {
98
struct smp_config_operations mps_config_operations = {
93
    .cpu_count = get_cpu_count,
99
    .cpu_count = get_cpu_count,
94
    .cpu_enabled = is_cpu_enabled,
100
    .cpu_enabled = is_cpu_enabled,
95
    .cpu_bootstrap = is_bsp,
101
    .cpu_bootstrap = is_bsp,
96
    .cpu_apic_id = get_cpu_apic_id,
102
    .cpu_apic_id = get_cpu_apic_id,
97
    .irq_to_pin = mps_irq_to_pin
103
    .irq_to_pin = mps_irq_to_pin
98
};
104
};
99
 
105
 
100
count_t get_cpu_count(void)
106
count_t get_cpu_count(void)
101
{
107
{
102
    return processor_entry_cnt;
108
    return processor_entry_cnt;
103
}
109
}
104
 
110
 
105
bool is_cpu_enabled(index_t i)
111
bool is_cpu_enabled(index_t i)
106
{
112
{
107
    ASSERT(i < processor_entry_cnt);
113
    ASSERT(i < processor_entry_cnt);
108
    return processor_entries[i].cpu_flags & 0x1;
114
    return processor_entries[i].cpu_flags & 0x1;
109
}
115
}
110
 
116
 
111
bool is_bsp(index_t i)
117
bool is_bsp(index_t i)
112
{
118
{
113
    ASSERT(i < processor_entry_cnt);
119
    ASSERT(i < processor_entry_cnt);
114
    return processor_entries[i].cpu_flags & 0x2;
120
    return processor_entries[i].cpu_flags & 0x2;
115
}
121
}
116
 
122
 
117
__u8 get_cpu_apic_id(index_t i)
123
__u8 get_cpu_apic_id(index_t i)
118
{
124
{
119
    ASSERT(i < processor_entry_cnt);
125
    ASSERT(i < processor_entry_cnt);
120
    return processor_entries[i].l_apic_id;
126
    return processor_entries[i].l_apic_id;
121
}
127
}
122
 
128
 
123
 
129
 
124
/*
130
/*
125
 * Used to check the integrity of the MP Floating Structure.
131
 * Used to check the integrity of the MP Floating Structure.
126
 */
132
 */
127
int mps_fs_check(__u8 *base)
133
int mps_fs_check(__u8 *base)
128
{
134
{
129
    int i;
135
    int i;
130
    __u8 sum;
136
    __u8 sum;
131
   
137
   
132
    for (i = 0, sum = 0; i < 16; i++)
138
    for (i = 0, sum = 0; i < 16; i++)
133
        sum += base[i];
139
        sum += base[i];
134
   
140
   
135
    return !sum;
141
    return !sum;
136
}
142
}
137
 
143
 
138
/*
144
/*
139
 * Used to check the integrity of the MP Configuration Table.
145
 * Used to check the integrity of the MP Configuration Table.
140
 */
146
 */
141
int mps_ct_check(void)
147
int mps_ct_check(void)
142
{
148
{
143
    __u8 *base = (__u8 *) ct;
149
    __u8 *base = (__u8 *) ct;
144
    __u8 *ext = base + ct->base_table_length;
150
    __u8 *ext = base + ct->base_table_length;
145
    __u8 sum;
151
    __u8 sum;
146
    int i; 
152
    int i; 
147
   
153
   
148
    /* count the checksum for the base table */
154
    /* count the checksum for the base table */
149
    for (i=0,sum=0; i < ct->base_table_length; i++)
155
    for (i=0,sum=0; i < ct->base_table_length; i++)
150
        sum += base[i];
156
        sum += base[i];
151
       
157
       
152
    if (sum)
158
    if (sum)
153
        return 0;
159
        return 0;
154
       
160
       
155
    /* count the checksum for the extended table */
161
    /* count the checksum for the extended table */
156
    for (i=0,sum=0; i < ct->ext_table_length; i++)
162
    for (i=0,sum=0; i < ct->ext_table_length; i++)
157
        sum += ext[i];
163
        sum += ext[i];
158
       
164
       
159
    return sum == ct->ext_table_checksum;
165
    return sum == ct->ext_table_checksum;
160
}
166
}
161
 
167
 
162
void mps_init(void)
168
void mps_init(void)
163
{
169
{
164
    __u8 *addr[2] = { NULL, (__u8 *) PA2KA(0xf0000) };
170
    __u8 *addr[2] = { NULL, (__u8 *) PA2KA(0xf0000) };
165
    int i, j, length[2] = { 1024, 64*1024 };
171
    int i, j, length[2] = { 1024, 64*1024 };
166
   
172
   
167
 
173
 
168
    /*
174
    /*
169
     * Find MP Floating Pointer Structure
175
     * Find MP Floating Pointer Structure
170
     * 1a. search first 1K of EBDA
176
     * 1a. search first 1K of EBDA
171
     * 1b. if EBDA is undefined, search last 1K of base memory
177
     * 1b. if EBDA is undefined, search last 1K of base memory
172
     *  2. search 64K starting at 0xf0000
178
     *  2. search 64K starting at 0xf0000
173
     */
179
     */
174
 
180
 
175
    addr[0] = (__u8 *) PA2KA(ebda ? ebda : 639 * 1024);
181
    addr[0] = (__u8 *) PA2KA(ebda ? ebda : 639 * 1024);
176
    for (i = 0; i < 2; i++) {
182
    for (i = 0; i < 2; i++) {
177
        for (j = 0; j < length[i]; j += 16) {
183
        for (j = 0; j < length[i]; j += 16) {
178
            if (*((__u32 *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) {
184
            if (*((__u32 *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) {
179
                fs = (struct mps_fs *) &addr[i][j];
185
                fs = (struct mps_fs *) &addr[i][j];
180
                goto fs_found;
186
                goto fs_found;
181
            }
187
            }
182
        }
188
        }
183
    }
189
    }
184
 
190
 
185
    return;
191
    return;
186
   
192
   
187
fs_found:
193
fs_found:
188
    printf("%p: MPS Floating Pointer Structure\n", fs);
194
    printf("%p: MPS Floating Pointer Structure\n", fs);
189
 
195
 
190
    if (fs->config_type == 0 && fs->configuration_table) {
196
    if (fs->config_type == 0 && fs->configuration_table) {
191
        if (fs->mpfib2 >> 7) {
197
        if (fs->mpfib2 >> 7) {
192
            printf("%s: PIC mode not supported\n", __FUNCTION__);
198
            printf("%s: PIC mode not supported\n", __FUNCTION__);
193
            return;
199
            return;
194
        }
200
        }
195
 
201
 
196
        ct = (struct mps_ct *)PA2KA((__address)fs->configuration_table);
202
        ct = (struct mps_ct *)PA2KA((__address)fs->configuration_table);
197
        config.cpu_count = configure_via_ct();
203
        config.cpu_count = configure_via_ct();
198
    }
204
    }
199
    else
205
    else
200
        config.cpu_count = configure_via_default(fs->config_type);
206
        config.cpu_count = configure_via_default(fs->config_type);
201
 
207
 
202
    return;
208
    return;
203
}
209
}
204
 
210
 
205
int configure_via_ct(void)
211
int configure_via_ct(void)
206
{
212
{
207
    __u8 *cur;
213
    __u8 *cur;
208
    int i, cnt;
214
    int i, cnt;
209
       
215
       
210
    if (ct->signature != CT_SIGNATURE) {
216
    if (ct->signature != CT_SIGNATURE) {
211
        printf("%s: bad ct->signature\n", __FUNCTION__);
217
        printf("%s: bad ct->signature\n", __FUNCTION__);
212
        return 1;
218
        return 1;
213
    }
219
    }
214
    if (!mps_ct_check()) {
220
    if (!mps_ct_check()) {
215
        printf("%s: bad ct checksum\n", __FUNCTION__);
221
        printf("%s: bad ct checksum\n", __FUNCTION__);
216
        return 1;
222
        return 1;
217
    }
223
    }
218
    if (ct->oem_table) {
224
    if (ct->oem_table) {
219
        printf("%s: ct->oem_table not supported\n", __FUNCTION__);
225
        printf("%s: ct->oem_table not supported\n", __FUNCTION__);
220
        return 1;
226
        return 1;
221
    }
227
    }
222
   
228
   
223
    l_apic = (__u32 *)(__address)ct->l_apic;
229
    l_apic = (__u32 *)(__address)ct->l_apic;
224
 
230
 
225
    cnt = 0;
231
    cnt = 0;
226
    cur = &ct->base_table[0];
232
    cur = &ct->base_table[0];
227
    for (i=0; i < ct->entry_count; i++) {
233
    for (i=0; i < ct->entry_count; i++) {
228
        switch (*cur) {
234
        switch (*cur) {
229
            /* Processor entry */
235
            /* Processor entry */
230
            case 0:
236
            case 0:
231
                processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur;
237
                processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur;
232
                processor_entry_cnt++;
238
                processor_entry_cnt++;
233
                cnt += ct_processor_entry((struct __processor_entry *) cur);
239
                cnt += ct_processor_entry((struct __processor_entry *) cur);
234
                cur += 20;
240
                cur += 20;
235
                break;
241
                break;
236
 
242
 
237
            /* Bus entry */
243
            /* Bus entry */
238
            case 1:
244
            case 1:
239
                bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur;
245
                bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur;
240
                bus_entry_cnt++;
246
                bus_entry_cnt++;
241
                ct_bus_entry((struct __bus_entry *) cur);
247
                ct_bus_entry((struct __bus_entry *) cur);
242
                cur += 8;
248
                cur += 8;
243
                break;
249
                break;
244
               
250
               
245
            /* I/O Apic */
251
            /* I/O Apic */
246
            case 2:
252
            case 2:
247
                io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur;
253
                io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur;
248
                io_apic_entry_cnt++;
254
                io_apic_entry_cnt++;
249
                ct_io_apic_entry((struct __io_apic_entry *) cur);
255
                ct_io_apic_entry((struct __io_apic_entry *) cur);
250
                cur += 8;
256
                cur += 8;
251
                break;
257
                break;
252
               
258
               
253
            /* I/O Interrupt Assignment */
259
            /* I/O Interrupt Assignment */
254
            case 3:
260
            case 3:
255
                io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur;
261
                io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur;
256
                io_intr_entry_cnt++;
262
                io_intr_entry_cnt++;
257
                ct_io_intr_entry((struct __io_intr_entry *) cur);
263
                ct_io_intr_entry((struct __io_intr_entry *) cur);
258
                cur += 8;
264
                cur += 8;
259
                break;
265
                break;
260
 
266
 
261
            /* Local Interrupt Assignment */
267
            /* Local Interrupt Assignment */
262
            case 4:
268
            case 4:
263
                l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur;
269
                l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur;
264
                l_intr_entry_cnt++;
270
                l_intr_entry_cnt++;
265
                ct_l_intr_entry((struct __l_intr_entry *) cur);
271
                ct_l_intr_entry((struct __l_intr_entry *) cur);
266
                cur += 8;
272
                cur += 8;
267
                break;
273
                break;
268
 
274
 
269
            default:
275
            default:
270
                /*
276
                /*
271
                 * Something is wrong. Fallback to UP mode.
277
                 * Something is wrong. Fallback to UP mode.
272
                 */
278
                 */
273
                 
279
                 
274
                printf("%s: ct badness\n", __FUNCTION__);
280
                printf("%s: ct badness\n", __FUNCTION__);
275
                return 1;
281
                return 1;
276
        }
282
        }
277
    }
283
    }
278
   
284
   
279
    /*
285
    /*
280
     * Process extended entries.
286
     * Process extended entries.
281
     */
287
     */
282
    ct_extended_entries();
288
    ct_extended_entries();
283
    return cnt;
289
    return cnt;
284
}
290
}
285
 
291
 
286
int configure_via_default(__u8 n)
292
int configure_via_default(__u8 n)
287
{
293
{
288
    /*
294
    /*
289
     * Not yet implemented.
295
     * Not yet implemented.
290
     */
296
     */
291
    printf("%s: not supported\n", __FUNCTION__);
297
    printf("%s: not supported\n", __FUNCTION__);
292
    return 1;
298
    return 1;
293
}
299
}
294
 
300
 
295
 
301
 
296
int ct_processor_entry(struct __processor_entry *pr)
302
int ct_processor_entry(struct __processor_entry *pr)
297
{
303
{
298
    /*
304
    /*
299
     * Ignore processors which are not marked enabled.
305
     * Ignore processors which are not marked enabled.
300
     */
306
     */
301
    if ((pr->cpu_flags & (1<<0)) == 0)
307
    if ((pr->cpu_flags & (1<<0)) == 0)
302
        return 0;
308
        return 0;
303
   
309
   
304
    apic_id_mask |= (1<<pr->l_apic_id);
310
    apic_id_mask |= (1<<pr->l_apic_id);
305
    return 1;
311
    return 1;
306
}
312
}
307
 
313
 
308
void ct_bus_entry(struct __bus_entry *bus)
314
void ct_bus_entry(struct __bus_entry *bus)
309
{
315
{
310
#ifdef MPSCT_VERBOSE
316
#ifdef MPSCT_VERBOSE
311
    char buf[7];
317
    char buf[7];
312
    memcpy((void *) buf, (void *) bus->bus_type, 6);
318
    memcpy((void *) buf, (void *) bus->bus_type, 6);
313
    buf[6] = 0;
319
    buf[6] = 0;
314
    printf("bus%d: %s\n", bus->bus_id, buf);
320
    printf("bus%d: %s\n", bus->bus_id, buf);
315
#endif
321
#endif
316
}
322
}
317
 
323
 
318
void ct_io_apic_entry(struct __io_apic_entry *ioa)
324
void ct_io_apic_entry(struct __io_apic_entry *ioa)
319
{
325
{
320
    static int io_apic_count = 0;
326
    static int io_apic_count = 0;
321
 
327
 
322
    /* this ioapic is marked unusable */
328
    /* this ioapic is marked unusable */
323
    if ((ioa->io_apic_flags & 1) == 0)
329
    if ((ioa->io_apic_flags & 1) == 0)
324
        return;
330
        return;
325
   
331
   
326
    if (io_apic_count++ > 0) {
332
    if (io_apic_count++ > 0) {
327
        /*
333
        /*
328
         * Multiple IO APIC's are currently not supported.
334
         * Multiple IO APIC's are currently not supported.
329
         */
335
         */
330
        return;
336
        return;
331
    }
337
    }
332
   
338
   
333
    io_apic = (__u32 *)(__address)ioa->io_apic;
339
    io_apic = (__u32 *)(__address)ioa->io_apic;
334
}
340
}
335
 
341
 
336
//#define MPSCT_VERBOSE
342
//#define MPSCT_VERBOSE
337
void ct_io_intr_entry(struct __io_intr_entry *iointr)
343
void ct_io_intr_entry(struct __io_intr_entry *iointr)
338
{
344
{
339
#ifdef MPSCT_VERBOSE
345
#ifdef MPSCT_VERBOSE
340
    switch (iointr->intr_type) {
346
    switch (iointr->intr_type) {
341
        case 0: printf("INT"); break;
347
        case 0: printf("INT"); break;
342
        case 1: printf("NMI"); break;
348
        case 1: printf("NMI"); break;
343
        case 2: printf("SMI"); break;
349
        case 2: printf("SMI"); break;
344
        case 3: printf("ExtINT"); break;
350
        case 3: printf("ExtINT"); break;
345
    }
351
    }
346
    putchar(',');
352
    putchar(',');
347
    switch (iointr->poel&3) {
353
    switch (iointr->poel&3) {
348
        case 0: printf("bus-like"); break;
354
        case 0: printf("bus-like"); break;
349
        case 1: printf("active high"); break;
355
        case 1: printf("active high"); break;
350
        case 2: printf("reserved"); break;
356
        case 2: printf("reserved"); break;
351
        case 3: printf("active low"); break;
357
        case 3: printf("active low"); break;
352
    }
358
    }
353
    putchar(',');
359
    putchar(',');
354
    switch ((iointr->poel>>2)&3) {
360
    switch ((iointr->poel>>2)&3) {
355
        case 0: printf("bus-like"); break;
361
        case 0: printf("bus-like"); break;
356
        case 1: printf("edge-triggered"); break;
362
        case 1: printf("edge-triggered"); break;
357
        case 2: printf("reserved"); break;
363
        case 2: printf("reserved"); break;
358
        case 3: printf("level-triggered"); break;
364
        case 3: printf("level-triggered"); break;
359
    }
365
    }
360
    putchar(',');
366
    putchar(',');
361
    printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq);
367
    printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq);
362
    putchar(',');
368
    putchar(',');
363
    printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
369
    printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
364
    putchar('\n'); 
370
    putchar('\n'); 
365
#endif
371
#endif
366
}
372
}
367
 
373
 
368
void ct_l_intr_entry(struct __l_intr_entry *lintr)
374
void ct_l_intr_entry(struct __l_intr_entry *lintr)
369
{
375
{
370
#ifdef MPSCT_VERBOSE
376
#ifdef MPSCT_VERBOSE
371
    switch (lintr->intr_type) {
377
    switch (lintr->intr_type) {
372
        case 0: printf("INT"); break;
378
        case 0: printf("INT"); break;
373
        case 1: printf("NMI"); break;
379
        case 1: printf("NMI"); break;
374
        case 2: printf("SMI"); break;
380
        case 2: printf("SMI"); break;
375
        case 3: printf("ExtINT"); break;
381
        case 3: printf("ExtINT"); break;
376
    }
382
    }
377
    putchar(',');
383
    putchar(',');
378
    switch (lintr->poel&3) {
384
    switch (lintr->poel&3) {
379
        case 0: printf("bus-like"); break;
385
        case 0: printf("bus-like"); break;
380
        case 1: printf("active high"); break;
386
        case 1: printf("active high"); break;
381
        case 2: printf("reserved"); break;
387
        case 2: printf("reserved"); break;
382
        case 3: printf("active low"); break;
388
        case 3: printf("active low"); break;
383
    }
389
    }
384
    putchar(',');
390
    putchar(',');
385
    switch ((lintr->poel>>2)&3) {
391
    switch ((lintr->poel>>2)&3) {
386
        case 0: printf("bus-like"); break;
392
        case 0: printf("bus-like"); break;
387
        case 1: printf("edge-triggered"); break;
393
        case 1: printf("edge-triggered"); break;
388
        case 2: printf("reserved"); break;
394
        case 2: printf("reserved"); break;
389
        case 3: printf("level-triggered"); break;
395
        case 3: printf("level-triggered"); break;
390
    }
396
    }
391
    putchar(',');
397
    putchar(',');
392
    printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq);
398
    printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq);
393
    putchar(',');
399
    putchar(',');
394
    printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
400
    printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
395
    putchar('\n');
401
    putchar('\n');
396
#endif
402
#endif
397
}
403
}
398
 
404
 
399
void ct_extended_entries(void)
405
void ct_extended_entries(void)
400
{
406
{
401
    __u8 *ext = (__u8 *) ct + ct->base_table_length;
407
    __u8 *ext = (__u8 *) ct + ct->base_table_length;
402
    __u8 *cur;
408
    __u8 *cur;
403
 
409
 
404
    for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) {
410
    for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) {
405
        switch (cur[CT_EXT_ENTRY_TYPE]) {
411
        switch (cur[CT_EXT_ENTRY_TYPE]) {
406
            default:
412
            default:
407
                printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]);
413
                printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]);
408
                break;
414
                break;
409
        }
415
        }
410
    }
416
    }
411
}
417
}
412
 
418
 
413
int mps_irq_to_pin(int irq)
419
int mps_irq_to_pin(int irq)
414
{
420
{
415
    int i;
421
    int i;
416
   
422
   
417
    for(i=0;i<io_intr_entry_cnt;i++) {
423
    for(i=0;i<io_intr_entry_cnt;i++) {
418
        if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0)
424
        if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0)
419
            return io_intr_entries[i].dst_io_apic_pin;
425
            return io_intr_entries[i].dst_io_apic_pin;
420
    }
426
    }
421
   
427
   
422
    return -1;
428
    return -1;
423
}
429
}
424
 
430
 
425
#endif /* CONFIG_SMP */
431
#endif /* CONFIG_SMP */
-
 
432
 
-
 
433
 /** @}
-
 
434
 */
-
 
435
 
426
 
436