Subversion Repositories HelenOS

Rev

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

Rev 2441 Rev 2701
Line 1... Line 1...
1
/*
1
/*
2
 * Copyright (c) 2005 Jakub Jermar
2
 * Copyright (c) 2008 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:
Line 70... Line 70...
70
    if (config.cpu_count == 1) {
70
    if (config.cpu_count == 1) {
71
        mps_init();
71
        mps_init();
72
        ops = &mps_config_operations;
72
        ops = &mps_config_operations;
73
    }
73
    }
74
 
74
 
75
    l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
75
    l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
-
 
76
        FRAME_ATOMIC | FRAME_KA);
76
    if (!l_apic_address)
77
    if (!l_apic_address)
77
        panic("cannot allocate address for l_apic\n");
78
        panic("cannot allocate address for l_apic\n");
78
 
79
 
79
    io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
80
    io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
-
 
81
        FRAME_ATOMIC | FRAME_KA);
80
    if (!io_apic_address)
82
    if (!io_apic_address)
81
        panic("cannot allocate address for io_apic\n");
83
        panic("cannot allocate address for io_apic\n");
82
 
84
 
83
    if (config.cpu_count > 1) {    
85
    if (config.cpu_count > 1) {    
84
        page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic,
86
        page_mapping_insert(AS_KERNEL, l_apic_address,
85
                  PAGE_NOT_CACHEABLE | PAGE_WRITE);
87
            (uintptr_t) l_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
86
        page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
88
        page_mapping_insert(AS_KERNEL, io_apic_address,
87
                  PAGE_NOT_CACHEABLE | PAGE_WRITE);
89
            (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
88
                 
90
                 
89
        l_apic = (uint32_t *) l_apic_address;
91
        l_apic = (uint32_t *) l_apic_address;
90
        io_apic = (uint32_t *) io_apic_address;
92
        io_apic = (uint32_t *) io_apic_address;
91
    }
93
    }
92
}
94
}
Line 110... Line 112...
110
     */
112
     */
111
 
113
 
112
    /*
114
    /*
113
     * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
115
     * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
114
     */
116
     */
-
 
117
    *((uint16_t *) (PA2KA(0x467 + 0))) =
115
    *((uint16_t *) (PA2KA(0x467 + 0))) = (uint16_t) (((uintptr_t) ap_boot) >> 4);   /* segment */
118
        (uint16_t) (((uintptr_t) ap_boot) >> 4);    /* segment */
116
    *((uint16_t *) (PA2KA(0x467 + 2))) = 0;             /* offset */
119
    *((uint16_t *) (PA2KA(0x467 + 2))) = 0;     /* offset */
117
   
120
   
118
    /*
121
    /*
119
     * Save 0xa to address 0xf of the CMOS RAM.
122
     * Save 0xa to address 0xf of the CMOS RAM.
120
     * BIOS will not do the POST after the INIT signal.
123
     * BIOS will not do the POST after the INIT signal.
121
     */
124
     */
Line 141... Line 144...
141
         */
144
         */
142
        if (ops->cpu_bootstrap(i))
145
        if (ops->cpu_bootstrap(i))
143
            continue;
146
            continue;
144
 
147
 
145
        if (ops->cpu_apic_id(i) == apic) {
148
        if (ops->cpu_apic_id(i) == apic) {
146
            printf("%s: bad processor entry #%u, will not send IPI to myself\n", __FUNCTION__, i);
149
            printf("%s: bad processor entry #%u, will not send IPI "
-
 
150
                "to myself\n", __FUNCTION__, i);
147
            continue;
151
            continue;
148
        }
152
        }
149
       
153
       
150
        /*
154
        /*
151
         * Prepare new GDT for CPU in question.
155
         * Prepare new GDT for CPU in question.
152
         */
156
         */
153
        if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS * sizeof(struct descriptor), FRAME_ATOMIC)))
157
        gdt_new = (struct descriptor *) malloc(GDT_ITEMS *
-
 
158
            sizeof(struct descriptor), FRAME_ATOMIC);
-
 
159
        if (!gdt_new)
154
            panic("couldn't allocate memory for GDT\n");
160
            panic("couldn't allocate memory for GDT\n");
155
 
161
 
156
        memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
162
        memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
157
        memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
163
        memsetb((uintptr_t)(&gdt_new[TSS_DES]),
-
 
164
            sizeof(struct descriptor), 0);
158
        protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
165
        protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
159
        protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
166
        protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
160
        gdtr.base = (uintptr_t) gdt_new;
167
        gdtr.base = (uintptr_t) gdt_new;
161
 
168
 
162
        if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
169
        if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
163
            /*
170
            /*
164
             * There may be just one AP being initialized at
171
             * There may be just one AP being initialized at
165
             * the time. After it comes completely up, it is
172
             * the time. After it comes completely up, it is
166
             * supposed to wake us up.
173
             * supposed to wake us up.
167
             */
174
             */
168
            if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
175
            if (waitq_sleep_timeout(&ap_completion_wq, 1000000,
-
 
176
                SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
169
                unsigned int cpu = (config.cpu_active > i) ? config.cpu_active : i;
177
                unsigned int cpu = (config.cpu_active > i) ?
-
 
178
                    config.cpu_active : i;
170
                printf("%s: waiting for cpu%u (APIC ID = %d) timed out\n", __FUNCTION__, cpu, ops->cpu_apic_id(i));
179
                printf("%s: waiting for cpu%u (APIC ID = %d) "
-
 
180
                    "timed out\n", __FUNCTION__, cpu,
-
 
181
                    ops->cpu_apic_id(i));
171
            }
182
            }
172
        } else
183
        } else
173
            printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
184
            printf("INIT IPI for l_apic%d failed\n",
-
 
185
                ops->cpu_apic_id(i));
174
    }
186
    }
175
}
187
}
176
 
188
 
177
int smp_irq_to_pin(unsigned int irq)
189
int smp_irq_to_pin(unsigned int irq)
178
{
190
{