Intel 64 and IA-32 Architectures Software Developers Manual Volume 3A, System Programming Guide, Part 1
7-42 Vol. 3A
MULTIPLE-PROCESSOR MANAGEMENT
4. Extract the initial APIC ID of a logical processor.
#define INITIAL_APIC_ID_BITS 0xFF000000 // CPUID.1.EBX[31:24] initial APIC ID
// Returns the 8-bit unique initial APIC ID for the processor running the code.
// Software can use OS services to affinitize the current thread to each logical processor
// available under the OS to gather the initial APIC_IDs for each logical processor.
unsigned char GetInitAPIC_ID (void)
{
unsigned int reg_ebx = 0;
execute cpuid with eax = 1
store returned value of ebx
return (unsigned char) ((reg_ebx & INITIAL_APIC_ID_BITS) >> 24;
}
5. Find the width of a bit-field mask from the maximum count of the bit-field.
// Returns the mask bit width of a bit field from the maximum count that bit field can represent.
// This algorithm does not assume ‘Max_Count’ to have a value equal to power of 2.
unsigned FindMaskWidth(Unsigned Max_Count)
{unsigned int mask_width, cnt = Max_Count;
__asm {
mov eax, cnt
mov ecx, 0
mov mask_width, ecx
dec eax
bsr cx, ax
jz next
inc cx
mov mask_width, ecx
next:
mov eax, mask_width
}
return mask_width;
}
6. Extract a sub ID given a full ID, maximum sub ID value and shift count.
// Returns the value of the sub ID, this is not a zero-based value
Unsigned char GetSubID(unsigned char Full_ID, unsigned char MaxSubIDvalue, unsigned char
Shift_Count)
{
MaskWidth = FindMaskWidth(MaxSubIDValue);
MaskBits = ((uchar) (0xff << Shift_Count)) ^ ((uchar) (0xff << Shift_Count + MaskWidth)) ;