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