added read_cpuid and MTRR support checking before trying to set them
[retrobench] / src / util_asm.s
diff --git a/src/util_asm.s b/src/util_asm.s
new file mode 100644 (file)
index 0000000..f237cf5
--- /dev/null
@@ -0,0 +1,67 @@
+       .text
+
+       .equ F_ID,      0x200000
+
+       .globl _read_cpuid
+       .globl read_cpuid
+_read_cpuid:
+read_cpuid:
+       # determine if cpuid is available
+       pushf
+       pop %eax
+       mov %eax, %edx  # keep a copy of the original eflags in edx
+       xor $F_ID, %eax
+       push %eax
+       popf
+       pushf
+       pop %eax
+       cmp %eax, %edx
+       jnz 0f
+       # failed to flip ID bit, CPUID not supported
+       mov $-1, %eax
+       ret
+0:
+       push %ebp
+       mov %esp, %ebp
+       push %ebx
+       push %edi
+       sub $8, %esp
+       mov 8(%ebp), %edi
+
+       xor %eax, %eax
+       mov %eax, (%esp)        # current index
+       cpuid
+
+       mov %eax, (%edi)
+       # clamp to the size of our cpuid_info structure
+       cmp $1, %eax
+       jbe 0f
+       mov $1, %eax
+0:     mov %eax, 4(%esp)       # maximum index
+
+       mov %ebx, 4(%edi)
+       mov %edx, 8(%edi)
+       mov %ecx, 12(%edi)
+       add $16, %edi
+
+cpuid_loop:
+       mov (%esp), %eax
+       inc %eax
+       cmp 4(%esp), %eax
+       ja cpuid_done
+       mov %eax, (%esp)
+       cpuid
+       mov %eax, (%edi)
+       mov %ebx, 4(%edi)
+       mov %edx, 8(%edi)
+       mov %ecx, 12(%edi)
+       add $16, %edi
+       jmp cpuid_loop
+
+cpuid_done:
+       add $8, %esp
+       pop %edi
+       pop %ebx
+       pop %ebp
+       xor %eax, %eax
+       ret