Rev 15 | Rev 21 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 15 | Rev 16 | ||
---|---|---|---|
Line 24... | Line 24... | ||
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 | #ifdef __SMP__ |
- | |
30 | - | ||
31 | #include <arch/types.h> |
29 | #include <arch/types.h> |
32 | #include <arch/smp/apic.h> |
30 | #include <arch/smp/apic.h> |
33 | #include <arch/smp/ap.h> |
31 | #include <arch/smp/ap.h> |
34 | #include <arch/smp/mp.h> |
32 | #include <arch/smp/mp.h> |
35 | #include <mm/page.h> |
33 | #include <mm/page.h> |
Line 37... | Line 35... | ||
37 | #include <arch/interrupt.h> |
35 | #include <arch/interrupt.h> |
38 | #include <print.h> |
36 | #include <print.h> |
39 | #include <arch/asm.h> |
37 | #include <arch/asm.h> |
40 | #include <arch.h> |
38 | #include <arch.h> |
41 | 39 | ||
- | 40 | #ifdef __SMP__ |
|
- | 41 | ||
42 | /* |
42 | /* |
43 | * This is functional, far-from-general-enough interface to the APIC. |
43 | * This is functional, far-from-general-enough interface to the APIC. |
44 | * Advanced Programmable Interrupt Controller for MP systems. |
44 | * Advanced Programmable Interrupt Controller for MP systems. |
45 | * Tested on: |
45 | * Tested on: |
46 | * Bochs 2.0.2 with 2-8 CPUs |
46 | * Bochs 2.0.2 with 2-8 CPUs |
Line 219... | Line 219... | ||
219 | } |
219 | } |
220 | 220 | ||
221 | void l_apic_init(void) |
221 | void l_apic_init(void) |
222 | { |
222 | { |
223 | __u32 tmp, t1, t2; |
223 | __u32 tmp, t1, t2; |
- | 224 | int cpu_id = config.cpu_active - 1; |
|
224 | 225 | ||
225 | 226 | ||
- | 227 | /* |
|
- | 228 | * Here we set local APIC ID's so that they match operating system's CPU ID's |
|
- | 229 | * This operation is dangerous as it is model specific. |
|
- | 230 | * TODO: some care should be taken. |
|
- | 231 | * NOTE: CPU may not be used to define APIC ID |
|
- | 232 | */ |
|
- | 233 | if (l_apic_id() != cpu_id) { |
|
- | 234 | l_apic[L_APIC_ID] &= L_APIC_IDClear; |
|
- | 235 | l_apic[L_APIC_ID] |= (l_apic[L_APIC_ID]&L_APIC_IDClear)|((cpu_id)<<L_APIC_IDShift); |
|
- | 236 | } |
|
- | 237 | ||
226 | l_apic[LVT_Err] |= (1<<16); |
238 | l_apic[LVT_Err] |= (1<<16); |
227 | l_apic[LVT_LINT0] |= (1<<16); |
239 | l_apic[LVT_LINT0] |= (1<<16); |
228 | l_apic[LVT_LINT1] |= (1<<16); |
240 | l_apic[LVT_LINT1] |= (1<<16); |
229 | 241 | ||
230 | tmp = l_apic[SVR] & SVRClear; |
242 | tmp = l_apic[SVR] & SVRClear; |
Line 268... | Line 280... | ||
268 | void l_apic_debug(void) |
280 | void l_apic_debug(void) |
269 | { |
281 | { |
270 | #ifdef LAPIC_VERBOSE |
282 | #ifdef LAPIC_VERBOSE |
271 | int i, lint; |
283 | int i, lint; |
272 | 284 | ||
273 | printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, (l_apic[L_APIC_ID] >> 24)&0xf); |
285 | printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id()); |
274 | 286 | ||
275 | printf("LVT_Tm: "); |
287 | printf("LVT_Tm: "); |
276 | if (l_apic[LVT_Tm] & (1<<17)) printf("periodic"); else printf("one-shot"); putchar(','); |
288 | if (l_apic[LVT_Tm] & (1<<17)) printf("periodic"); else printf("one-shot"); putchar(','); |
277 | if (l_apic[LVT_Tm] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); |
289 | if (l_apic[LVT_Tm] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); |
278 | if (l_apic[LVT_Tm] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); |
290 | if (l_apic[LVT_Tm] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); |
Line 302... | Line 314... | ||
302 | printf("%B\n", l_apic[LVT_Err] & 0xff); |
314 | printf("%B\n", l_apic[LVT_Err] & 0xff); |
303 | 315 | ||
304 | /* |
316 | /* |
305 | * This register is supported only on P6 and higher. |
317 | * This register is supported only on P6 and higher. |
306 | */ |
318 | */ |
307 | if (CPU->family > 5) { |
319 | if (CPU->arch.family > 5) { |
308 | printf("LVT_PCINT: "); |
320 | printf("LVT_PCINT: "); |
309 | if (l_apic[LVT_PCINT] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); |
321 | if (l_apic[LVT_PCINT] & (1<<16)) printf("masked"); else printf("not masked"); putchar(','); |
310 | if (l_apic[LVT_PCINT] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); |
322 | if (l_apic[LVT_PCINT] & (1<<12)) printf("send pending"); else printf("idle"); putchar(','); |
311 | switch ((l_apic[LVT_PCINT] >> 8)&7) { |
323 | switch ((l_apic[LVT_PCINT] >> 8)&7) { |
312 | case 0: printf("fixed"); break; |
324 | case 0: printf("fixed"); break; |
Line 323... | Line 335... | ||
323 | { |
335 | { |
324 | l_apic_eoi(); |
336 | l_apic_eoi(); |
325 | clock(); |
337 | clock(); |
326 | } |
338 | } |
327 | 339 | ||
- | 340 | __u8 l_apic_id(void) |
|
- | 341 | { |
|
- | 342 | return (l_apic[L_APIC_ID] >> L_APIC_IDShift)&L_APIC_IDMask; |
|
- | 343 | } |
|
- | 344 | ||
328 | __u32 io_apic_read(__u8 address) |
345 | __u32 io_apic_read(__u8 address) |
329 | { |
346 | { |
330 | __u32 tmp; |
347 | __u32 tmp; |
331 | 348 | ||
332 | tmp = io_apic[IOREGSEL] & ~0xf; |
349 | tmp = io_apic[IOREGSEL] & ~0xf; |