Subversion Repositories Kolibri OS

Rev

Rev 1905 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.         getcpucpuflags: get cpuflags for ia32
  3.  
  4.         copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
  5.         see COPYING and AUTHORS files in distribution or http:#mpg123.org
  6.         initially written by KIMURA Takuhiro (for 3DNow!)
  7.         extended for general use by Thomas Orgis
  8.  
  9.          extern int getcpuid(struct cpuflags*)
  10.         or just
  11.          extern int getcpuid(unsigned int*)
  12.         where there is memory for 4 ints
  13.          -> the first set of idflags (basic cpu family info)
  14.             and the idflags, stdflags, std2flags, extflags written to the parameter
  15.          -> 0x00000000 (CPUID instruction not supported)
  16. */
  17.  
  18. #include "mangle.h"
  19.  
  20. .text
  21.         ALIGN4
  22.  
  23. .globl ASM_NAME(getcpuflags)
  24. /*      .type ASM_NAME(getcpuflags),@function */
  25. ASM_NAME(getcpuflags):
  26.         pushl %ebp
  27.         movl %esp,%ebp
  28.         pushl %edx
  29.         pushl %ecx
  30.         pushl %ebx
  31.         pushl %esi
  32. /* get the int pointer for storing the flags */
  33.         movl 8(%ebp), %esi
  34. /* does that one make sense? */
  35.         movl $0x80000000,%eax
  36. /* now save the flags and do a check for cpuid availability */
  37.         pushfl
  38.         pushfl
  39.         popl %eax
  40.         movl %eax,%ebx
  41. /* set that bit... */
  42.         xorl $0x00200000,%eax
  43.         pushl %eax
  44.         popfl
  45. /* ...and read back the flags to see if it is understood */
  46.         pushfl
  47.         popl %eax
  48.         popfl
  49.         cmpl %ebx,%eax
  50.         je .Lnocpuid
  51. /* In principle, I would have to check the CPU's identify first to be sure how to interpret the extended flags. */
  52. /* now get the info, first extended */
  53.         movl $0x0, 12(%esi) /* clear value */
  54. /* only if supported... */
  55.         movl $0x80000000, %eax
  56.         cpuid
  57. /* IDT CPUs should not change EAX, generally I hope that non-3DNow cpus do not set a bogus support level here. */
  58.         cmpl $0x80000001, %eax
  59.         jb .Lnoextended /* Skip ext check without minimal support level. */
  60. /* is supported, get flags value */
  61.         movl $0x80000001,%eax
  62.         cpuid
  63.         movl %edx,12(%esi)
  64. .Lnoextended:
  65. /* then the other ones, called last to get the id flags in %eax for ret */
  66.         movl $0x00000001,%eax
  67.         cpuid
  68.         movl %eax, (%esi)
  69.         movl %ecx, 4(%esi)
  70.         movl %edx, 8(%esi)
  71.         jmp .Lend
  72.         ALIGN4
  73. .Lnocpuid:
  74. /* error: set everything to zero */
  75.         movl $0, %eax
  76.         movl $0, (%esi)
  77.         movl $0, 4(%esi)
  78.         movl $0, 8(%esi)
  79.         movl $0, 12(%esi)
  80.         ALIGN4
  81. .Lend:
  82. /* return value are the id flags, still stored in %eax */
  83.         popl %esi
  84.         popl %ebx
  85.         popl %ecx
  86.         popl %edx
  87.         movl %ebp,%esp
  88.         popl %ebp
  89.         ret
  90.  
  91. NONEXEC_STACK
  92.