2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
6 #include <exec/memory.h>
7 #include <proto/exec.h>
9 #include "kernel_base.h"
10 #include "kernel_debug.h"
11 #include "kernel_intern.h"
16 /* Initialize APIC by probing */
17 struct APICData
*core_APIC_Probe(void)
19 struct APICData
*data
;
23 /* Only i386 needs detection. On x86-64 APIC is always present. */
27 asm volatile("cpuid":"+a"(arg
),"=d"(res
)::"%ebx", "%ecx");
29 if (!(res
& (1 << 9)))
32 D(bug("[APIC] Detected by CPUID instruction\n"));
35 /* Assuming uniprocessor IBM PC compatible */
36 data
= AllocMem(sizeof(struct APICData
) + sizeof(struct CPUData
), MEMF_CLEAR
);
40 D(bug("[APIC] APIC Data @ 0x%p\n", data
));
42 if ((ssp
= SuperState()) != NULL
)
44 data
->lapicBase
= core_APIC_GetBase();
46 D(bug("[APIC] APIC Base = 0x%p\n", data
->lapicBase
));
49 data
->flags
= APF_8259
;
50 data
->cores
[0].cpu_LocalID
= core_APIC_GetID(data
->lapicBase
);
54 D(bug("[APIC] ID #%d\n", data
->cores
[0].cpu_LocalID
));
56 data
->cores
[0].cpu_GDT
= __KernBootPrivate
->BOOTGDT
;
57 data
->cores
[0].cpu_TLS
= __KernBootPrivate
->BOOTTLS
;
58 data
->cores
[0].cpu_IDT
= __KernBootPrivate
->BOOTIDT
;
59 data
->cores
[0].cpu_MMU
= &__KernBootPrivate
->MMU
;
61 /* Just initialize to default state */
62 core_APIC_Init(data
, 0);
66 FreeMem(data
, sizeof(struct APICData
) + sizeof(struct CPUData
));
72 apicid_t
core_APIC_GetNumberFromLocal(struct APICData
*data
, apicid_t apicLocalID
)
76 D(bug("[APIC] %s()\n", __func__
));
80 /* No APIC data -> uniprocessor system */
87 for (__APICNo
= 0; __APICNo
< data
->apic_count
; __APICNo
++)
89 if (data
->cores
[__APICNo
].cpu_LocalID
== apicLocalID
)
96 apicid_t
core_APIC_GetNumber(struct APICData
*data
)
98 apicid_t __APICLogicalID
;
100 D(bug("[APIC] %s()\n", __func__
));
104 D(bug("[APIC] %s: BSP or uniprocessor\n", __func__
));
105 /* No APIC data -> uniprocessor system */
109 __APICLogicalID
= core_APIC_GetID(data
->lapicBase
);
111 D(bug("[APIC] %s: APIC ID %03u\n", __func__
, __APICLogicalID
));
113 return core_APIC_GetNumberFromLocal(data
, __APICLogicalID
);
116 void core_APIC_GetMask(struct APICData
*data
, apicid_t cpuNo
, cpumask_t
*mask
)
121 D(bug("[APIC] %s()\n", __func__
));
123 if ((IPTR
)mask
!= TASKAFFINITY_ANY
)
126 idbit
= cpuNo
- (idlong
* 32);
128 D(bug("[APIC] %s: %d -> %d:%d\n", __func__
, cpuNo
, idlong
, idbit
));
129 D(bug("[APIC] %s: mask @ 0x%p\n", __func__
, mask
));
131 if ((apicMask
= (ULONG
*)mask
) != NULL
)
132 apicMask
[idlong
] = (1 << idbit
);
138 BOOL
core_APIC_CPUInMask(apicid_t cpuNo
, cpumask_t
*mask
)
143 D(bug("[APIC] %s()\n", __func__
));
152 if ((IPTR
)mask
== TASKAFFINITY_ANY
)
154 // TODO: make sure it is a valid cpu number in the range of available cpus.
159 idbit
= cpuNo
- (idlong
* 32);
161 D(bug("[APIC] %s: %d -> %d:%d\n", __func__
, cpuNo
, idlong
, idbit
));
162 D(bug("[APIC] %s: mask @ 0x%p\n", __func__
, mask
));
164 if (((apicMask
= (ULONG
*)mask
) != NULL
) && (apicMask
[idlong
] & (1 << idbit
)))