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 | { |