#include <palacios/vmm_types.h>
-#define CPUID_FEATURE_IDS 0x80000001
+#define CPUID_FEATURE_IDS 0x00000001
#define CPUID_EXT_FEATURE_IDS 0x80000001
-
-#ifdef __V3_32BIT__
-
-static void __inline__ v3_cpuid(uint_t target, addr_t * eax, addr_t * ebx, addr_t * ecx, addr_t * edx) {
+struct seg_selector {
+ union {
+ uint16_t value;
+ struct {
+ uint8_t rpl : 2;
+ uint8_t ti : 1;
+ uint16_t si : 13;
+ } __attribute__((packed));
+ } __attribute__((packed));
+} __attribute__((packed));
+
+struct gen_segment {
+ uint16_t limit_lo;
+ uint32_t base_lo : 24;
+ uint8_t type : 4;
+ uint8_t system : 1;
+ uint8_t dpl : 2;
+ uint8_t present : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avail : 1;
+ uint8_t long_mode : 1;
+ uint8_t db : 1;
+ uint8_t granularity : 1;
+ uint8_t base_hi : 8;
+} __attribute__((packed));
+
+struct sys_segment64 {
+ uint16_t limit_lo;
+ uint32_t base_lo : 24;
+ uint8_t type : 4;
+ uint8_t rsvd0 : 1;
+ uint8_t dpl : 2;
+ uint8_t present : 1;
+ uint8_t limit_hi : 4;
+ uint8_t avail : 1;
+ uint8_t rsvd1 : 3;
+ uint8_t granularity : 1;
+ uint64_t base_hi : 40;
+ uint32_t rsvd2;
+} __attribute__((packed));
+
+
+
+static void __inline__ v3_cpuid(uint32_t target,
+ uint32_t * eax, uint32_t * ebx,
+ uint32_t * ecx, uint32_t * edx) {
+#ifdef __V3_64BIT__
+ // avoid rbx on -FPIC - gcc likes to own rbx even on 64 bit PIC code
__asm__ __volatile__ (
- "pushl %%ebx\n\t"
+ "pushq %%rbx\n\t"
+ "movq %%rdi, %%rbx\n\t"
"cpuid\n\t"
- "movl %%ebx, %%esi\n\t"
- "popl %%ebx\n\t"
- : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
- : "a" (target)
+ "movq %%rbx, %%rdi\n\t"
+ "popq %%rbx\n\t"
+ : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "0" (target), "2" (*ecx)
);
- return;
-}
-
-#elif __V3_64BIT__
-
-static void __inline__ v3_cpuid(uint_t target, addr_t * eax, addr_t * ebx, addr_t * ecx, addr_t * edx) {
+#elif __V3_32BIT__
+ // 32 bit code compiled with -fPIC, cannot use ebx as an ouput reg. Fantastic.
__asm__ __volatile__ (
- "pushq %%rbx\n\t"
+ "pushl %%ebx\n\t"
+ "movl %%edi, %%ebx\n\t"
"cpuid\n\t"
- "movq %%rbx, %%rsi\n\t"
- "popq %%rbx\n\t"
- : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
- : "a" (target)
+ "movl %%ebx, %%edi\n\t"
+ "popl %%ebx\n\t"
+ : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "0" (target), "2" (*ecx)
);
+#endif
return;
}
-#endif
-
static void __inline__ v3_set_msr(uint_t msr, uint_t high_byte, uint_t low_byte) {
__asm__ __volatile__ (