Hi,
Thanks for your reply. I want to target both x86 and x64 bit platform.
will this work on x64 platform ? Like on Win64bit i have to use some __cpuid C++ instrinsic so the same applies for Linux64bit also ?
Main Topics
Browse All TopicsHi,
The following code works for Win32bit platfomr properly, how can i port the same code on Linux platfrom,
using c or c++ language only, can someone point out how to port the following code to linux platfrom.
#define INITIAL_APIC_ID_BITS 0xFF000000 // EBX[31:24] unique APIC ID
int get_APICID()
{
int nAPICPhysicalID = 0;
unsigned nIds;
unsigned int reg_ebx = 0;
__asm
{
mov eax, 1
cpuid
mov reg_ebx, ebx
}
nAPICPhysicalID = ((reg_ebx & INITIAL_APIC_ID_BITS) >> 24);
return nAPICPhysicalID ;
}
Thanks in advance,
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Hi,
I tried the above solution, but it does not return any value, on Linux rhel4.tpp.com 2.6.9-5.EL i686 i686 i386 GNU/Linux machine. where as i found a link, (http://fresh.t-systems-sf
Could you please have a look at it, and suggest the require changes.
Thanks,
Hi, Please have a look the below routine which i am trying to build to get the desired value, means different APIC ID's. I want to do the statatical sampling of APIC ID's.
When i tried to run the following routine, its give en error with gcc version 3.4.3 20041212 (Red Hat 3.4.3-9.EL4).
./neel: Exec format error. Wrong Architecture.
Please suggest.
#define INITIAL_APIC_ID_BITS 0xFF000000 /* EBX[31:24] unique APIC ID */
#include <stdio.h>
int get_APICID() {
unsigned int reg_eax = 1;
unsigned int reg_ebx = 0;
__asm__ (
"cpuid\n\t"
: "=b" (reg_ebx)
: "a" (reg_eax)
);
return ((reg_ebx & INITIAL_APIC_ID_BITS) >> 24);
}
int main()
{
int n;
for(int i=0; i<= 40; i++)
{
n = get_APICID();
printf("value %d", n);
}
}
Under Linux it's likely the CPUID instruction is not available to user applications, or is emulated by the kernel and may not return the true info you're looking for.
Also the info you would get is generally not useful under Linux, as user programs can't do anything directly with the hardware.
What exactly are you trying to do? Are you trying to reprogram the interrupt controller? You can't do it this way at all under Linux.
There's probably a better and cleaner way.
Hi,
The following code is working for x86 i686 architecture. Now, when i tried to run on x64_64 arch. its not giving me the same output ? Could anyone suggest what need to be taken care while porting the following asm to x86_64 bit architecture ?
#define WORD_EAX 0
#define WORD_EBX 1
#define WORD_ECX 2
#define WORD_EDX 3
#define WORD_NUM 4
unsinged int reg=1;
unsigned int words[WORD_NUM];
__asm__("cpuid"
: "=a" (words[WORD_EAX]), /* output */
"=b" (words[WORD_EBX]),
"=c" (words[WORD_ECX]),
"=d" (words[WORD_EDX])
: "a" (reg)); /* input */
return ((words[WORD_EBX] & INITIAL_APIC_ID_BITS) >> 24)
Thanks,
Please read this carefully:
You are barking up the wrong tree.
On windows, it's quite possible to access the interrupt hardware. Not trivial, as the system tries to protect that stuff, but possible.
On Linux, by design, the system hides all the hardware-specific stuff. You might THINK you're doing a CPUID instruction, but all the hardware-dependent instructions generate an invisible trap to the kernel, which is free to do anything it wants. Now in several cases, the kernel kinda emulates the instruction if it's not a dangerous one. For example, there's not much harm in revealing some of the CPU attributes with CPUID. But then again, no guarantees. The kernel might decide to present the CPU as a generic one, with some default and unrealistic values for its features.
Even if the kernel gives you some ACPID information, you generally can't do anything useful with this information. Linux will most certainly not let you poke or peek at the control registers. All low-level device control must be done by the kernel and associated drivers. users are not allowed to change critical system values as that will likely destabilize or crash the whole system.
You need to do a major rethink of what your goal is and design a way to accomplish it on Linux. You can't just blindly convert this kind of code from Windows to Linux.
Hi,
Ok, agreed, but we can use something like:
The sample C program:
#include <stdio.h>
#define WORD_EAX 0
#define WORD_EBX 1
#define WORD_ECX 2
#define WORD_EDX 3
#define WORD_NUM 4
#define INITIAL_APIC_ID_BITS 0xFF000000
int get_APICID(){
unsigned int words[WORD_NUM];
unsigned int reg = 1;
__asm__ ("pushl %%ebx \n\t" /* save %ebx */
"cpuid \n\t"
"movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */
"popl %%ebx \n\t" /* restore the old %ebx */
: "=a" (words[WORD_EAX]), /* output */
"=b" (words[WORD_EBX]),
"=c" (words[WORD_ECX]),
"=d" (words[WORD_EDX])
: "a" (reg)); /* input */
return ((words[WORD_EBX] & INITIAL_APIC_ID_BITS) >> 24);
}
found at : http://sam.zoy.org/blog/20
but still i am getting an error: error: can't find a register in class `BREG' while reloading `asm'
Could you suggest where did i go wrong ? even though the site says its correct program?
Thanks in advance for your help.
>> >> its not giving me the same output ?
>>
>> Can you show both values ?
I asked this earlier, and you haven't answered it.
I just tried running it on an x86_64 machine (AMD64) running Gentoo Linux, and the code I posted in my first post works fine. It returns 0, which is the expected APIC id for a single core, single processor system, which it is (I also verified that APIC and cpuid are enabled in the kernel).
Also check this document, which explains why this is the expected value :
http://www.amd.com/us-en/a
As I tried to explain a few times, the original code I posted in http:#20741653 should work fine.
I suspect however that the author misinterpreted the returned value (as explained in http:#20805023). There's no confirmation of that, since the author never really responded to any of my comments about that.
Furthermore, grg99's post http:#20745939 points out that your kernel has to support retrieving that information (just enable APIC and cpuid in it). And duncan_roe gives an alternative approach in http:#20747117.
So, to re-cap, I recommend a PAQ for :
http:#20741653 (Infinity08)
http:#20745939 (grg99)
http:#20747117 (duncan_roe)
http:#20805023 (Infinity08)
Business Accounts
Answer for Membership
by: Infinity08Posted on 2008-01-25 at 03:47:49ID: 20741653
I assume that the architecture is the same (x86, to be able to use the cpuid instruction).
What compiler are you using ? I assume gcc ?
Try this :
Select allOpen in new window