Subversion Repositories HelenOS

Rev

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

Rev 2222 Rev 2441
Line 96... Line 96...
96
 * that we need an arrangement like this (AP's being initialized by a kernel
96
 * that we need an arrangement like this (AP's being initialized by a kernel
97
 * thread), for a thread has its dedicated stack. (The stack used during the
97
 * thread), for a thread has its dedicated stack. (The stack used during the
98
 * BSP initialization (prior the very first call to scheduler()) will be used
98
 * BSP initialization (prior the very first call to scheduler()) will be used
99
 * as an initialization stack for each AP.)
99
 * as an initialization stack for each AP.)
100
 */
100
 */
101
void kmp(void *arg)
101
void kmp(void *arg __attribute__((unused)))
102
{
102
{
103
    unsigned int i;
103
    unsigned int i;
104
   
104
   
105
    ASSERT(ops != NULL);
105
    ASSERT(ops != NULL);
106
 
106
 
Line 110... Line 110...
110
     */
110
     */
111
 
111
 
112
    /*
112
    /*
113
     * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
113
     * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
114
     */
114
     */
115
    *((uint16_t *) (PA2KA(0x467 + 0))) =  ((uintptr_t) ap_boot) >> 4;   /* segment */
115
    *((uint16_t *) (PA2KA(0x467 + 0))) = (uint16_t) (((uintptr_t) ap_boot) >> 4);   /* segment */
116
    *((uint16_t *) (PA2KA(0x467 + 2))) =  0;                /* offset */
116
    *((uint16_t *) (PA2KA(0x467 + 2))) = 0;             /* offset */
117
   
117
   
118
    /*
118
    /*
119
     * Save 0xa to address 0xf of the CMOS RAM.
119
     * Save 0xa to address 0xf of the CMOS RAM.
120
     * BIOS will not do the POST after the INIT signal.
120
     * BIOS will not do the POST after the INIT signal.
121
     */
121
     */
122
    outb(0x70, 0xf);
122
    outb(0x70, 0xf);
123
    outb(0x71, 0xa);
123
    outb(0x71, 0xa);
124
 
124
 
125
    pic_disable_irqs(0xffff);
125
    pic_disable_irqs(0xffff);
126
    apic_init();
126
    apic_init();
-
 
127
   
-
 
128
    uint8_t apic = l_apic_id();
127
 
129
 
128
    for (i = 0; i < ops->cpu_count(); i++) {
130
    for (i = 0; i < ops->cpu_count(); i++) {
129
        struct descriptor *gdt_new;
131
        struct descriptor *gdt_new;
130
   
132
   
131
        /*
133
        /*
Line 138... Line 140...
138
         * The bootstrap processor is already up.
140
         * The bootstrap processor is already up.
139
         */
141
         */
140
        if (ops->cpu_bootstrap(i))
142
        if (ops->cpu_bootstrap(i))
141
            continue;
143
            continue;
142
 
144
 
143
        if (ops->cpu_apic_id(i) == l_apic_id()) {
145
        if (ops->cpu_apic_id(i) == apic) {
144
            printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i);
146
            printf("%s: bad processor entry #%u, will not send IPI to myself\n", __FUNCTION__, i);
145
            continue;
147
            continue;
146
        }
148
        }
147
       
149
       
148
        /*
150
        /*
149
         * Prepare new GDT for CPU in question.
151
         * Prepare new GDT for CPU in question.
150
         */
152
         */
151
        if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC)))
153
        if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS * sizeof(struct descriptor), FRAME_ATOMIC)))
152
            panic("couldn't allocate memory for GDT\n");
154
            panic("couldn't allocate memory for GDT\n");
153
 
155
 
154
        memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
156
        memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
155
        memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
157
        memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
156
        protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
158
        protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
Line 161... Line 163...
161
            /*
163
            /*
162
             * There may be just one AP being initialized at
164
             * There may be just one AP being initialized at
163
             * the time. After it comes completely up, it is
165
             * the time. After it comes completely up, it is
164
             * supposed to wake us up.
166
             * supposed to wake us up.
165
             */
167
             */
166
            if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
168
            if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
-
 
169
                unsigned int cpu = (config.cpu_active > i) ? config.cpu_active : i;
167
                printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i));
170
                printf("%s: waiting for cpu%u (APIC ID = %d) timed out\n", __FUNCTION__, cpu, ops->cpu_apic_id(i));
-
 
171
            }
168
        } else
172
        } else
169
            printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
173
            printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
170
    }
174
    }
171
}
175
}
172
 
176