#include static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ asm volatile("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (*eax), "2" (*ecx)); } int main(int argc, char **argv) { /* This programm prints some CPUID information and tests the SGX support of the CPU */ unsigned eax, ebx, ecx, edx; eax = 1; /* processor info and feature bits */ native_cpuid(&eax, &ebx, &ecx, &edx); printf("eax: %x ebx: %x ecx: %x edx: %x\n", eax, ebx, ecx, edx); printf("stepping %d\n", eax & 0xF); // Bit 3-0 printf("model %d\n", (eax >> 4) & 0xF); // Bit 7-4 printf("family %d\n", (eax >> 8) & 0xF); // Bit 11-8 printf("processor type %d\n", (eax >> 12) & 0x3); // Bit 13-12 printf("extended model %d\n", (eax >> 16) & 0xF); // Bit 19-16 printf("extended family %d\n", (eax >> 20) & 0xFF); // Bit 27-20 // if smx set - SGX global enable is supported printf("smx: %d\n", (ecx >> 6) & 1); // CPUID.1:ECX.[bit6] /* Extended feature bits (EAX=07H, ECX=0H)*/ printf("\nExtended feature bits (EAX=07H, ECX=0H)\n"); eax = 7; ecx = 0; native_cpuid(&eax, &ebx, &ecx, &edx); printf("eax: %x ebx: %x ecx: %x edx: %x\n", eax, ebx, ecx, edx); //CPUID.(EAX=07H, ECX=0H):EBX.SGX = 1, printf("sgx available: %d\n", (ebx >> 2) & 0x1); /* SGX has to be enabled in MSR.IA32_Feature_Control.SGX_Enable check with msr-tools: rdmsr -ax 0x3a SGX_Enable is Bit 18 if SGX_Enable = 0 no leaf information will appear. for more information check Intel Docs Architectures-software-developer-system-programming-manual - 35.1 Architectural MSRS */ /* CPUID Leaf 12H, Sub-Leaf 0 Enumeration of Intel SGX Capabilities (EAX=12H,ECX=0) */ printf("\nCPUID Leaf 12H, Sub-Leaf 0 of Intel SGX Capabilities (EAX=12H,ECX=0)\n"); eax = 0x12; ecx = 0; native_cpuid(&eax, &ebx, &ecx, &edx); printf("eax: %x ebx: %x ecx: %x edx: %x\n", eax, ebx, ecx, edx); printf("sgx 1 supported: %d\n", eax & 0x1); printf("sgx 2 supported: %d\n", (eax >> 1) & 0x1); printf("MaxEnclaveSize_Not64: %x\n", edx & 0xFF); printf("MaxEnclaveSize_64: %x\n", (edx >> 8) & 0xFF); /* CPUID Leaf 12H, Sub-Leaf 1 Enumeration of Intel SGX Capabilities (EAX=12H,ECX=1) */ printf("\nCPUID Leaf 12H, Sub-Leaf 1 of Intel SGX Capabilities (EAX=12H,ECX=1)\n"); eax = 0x12; ecx = 1; native_cpuid(&eax, &ebx, &ecx, &edx); printf("eax: %x ebx: %x ecx: %x edx: %x\n", eax, ebx, ecx, edx); int i; for (i=2; i<10; i++) { /* CPUID Leaf 12H, Sub-Leaf i Enumeration of Intel SGX Capabilities (EAX=12H,ECX=i) */ printf("\nCPUID Leaf 12H, Sub-Leaf %d of Intel SGX Capabilities (EAX=12H,ECX=%d)\n",i,i); eax = 0x12; ecx = i; native_cpuid(&eax, &ebx, &ecx, &edx); printf("eax: %x ebx: %x ecx: %x edx: %x\n", eax, ebx, ecx, edx); } }