No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

processor.c 3.0 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * libcaca
  3. * libcaca Colour ASCII-Art library
  4. * Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
  5. * 2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
  6. * All Rights Reserved
  7. *
  8. * $Id: kernel.h 4154 2009-12-20 13:33:11Z jylam $
  9. *
  10. * This library is free software. It comes without any warranty, to
  11. * the extent permitted by applicable law. You can redistribute it
  12. * and/or modify it under the terms of the Do What The Fuck You Want
  13. * To Public License, Version 2, as published by Sam Hocevar. See
  14. * http://sam.zoy.org/wtfpl/COPYING for more details.
  15. */
  16. #include "kernel.h"
  17. #include "klibc.h"
  18. #include "drivers/timer.h"
  19. #include "processor.h"
  20. int processor_get_info(struct processor_info *processor_info)
  21. {
  22. processor_info->id = 0;
  23. /* Vendor String */
  24. int code = CPUID_GETVENDORSTRING;
  25. unsigned int where[5];
  26. char *s;
  27. asm volatile ("cpuid":"=a" (*where), "=b"(*(where + 1)),
  28. "=c"(*(where + 2)), "=d"(*(where + 3)):"0"(code));
  29. s = (char *)where;
  30. unsigned int a = 0;
  31. unsigned int b = where[1];
  32. unsigned int d = where[3];
  33. unsigned int c = where[2];
  34. where[0] = b;
  35. where[1] = d;
  36. where[2] = c;
  37. where[3] = 0;
  38. memcpy(processor_info->vendor, where, 13);
  39. /* Features */
  40. code = CPUID_GETFEATURES;
  41. asm volatile ("cpuid":"=a" (a), "=d"(d):"0"(code):"ecx", "ebx");
  42. processor_info->features = a;
  43. processor_info->frequency = 0;
  44. processor_info->frequency = processor_get_frequency(processor_info);
  45. return 0;
  46. }
  47. u32 processor_get_frequency(struct processor_info * processor_info)
  48. {
  49. if (processor_info->frequency)
  50. return processor_info->frequency;
  51. u64 srdtsc64, erdtsc64;
  52. u32 srdtsc_l, srdtsc_h;
  53. u32 erdtsc_l, erdtsc_h;
  54. rdtsc(srdtsc_l, srdtsc_h); /* Get RDTSC */
  55. sleep(2); /* Sleep for 2 seconds */
  56. rdtsc(erdtsc_l, erdtsc_h); /* Get RDTSC again */
  57. srdtsc64 = srdtsc_h;
  58. srdtsc64 <<= 32;
  59. srdtsc64 |= srdtsc_l;
  60. erdtsc64 = erdtsc_h;
  61. erdtsc64 <<= 32;
  62. erdtsc64 |= erdtsc_l;
  63. u32 diff = erdtsc64 - srdtsc64; /* Cycle count for 2 seconds */
  64. diff /= 2; /* Divide by 2 to get cycles per sec */
  65. return diff;
  66. }
  67. void processor_print_info(struct processor_info *processor_info)
  68. {
  69. printf("CPU%d\n", processor_info->id);
  70. printf("Vendor ID : %s\n", processor_info->vendor);
  71. printf("Frequency : ");
  72. if (processor_info->frequency > 1000000000)
  73. {
  74. printf("%dGhz",
  75. processor_info->frequency / 1000000000);
  76. }
  77. else if (processor_info->frequency > 1000000)
  78. {
  79. printf("%dMhz",
  80. processor_info->frequency / 1000000);
  81. }
  82. else if (processor_info->frequency > 1000)
  83. {
  84. printf("%dKhz\n",
  85. processor_info->frequency / 1000);
  86. }
  87. else
  88. {
  89. printf("%dhz\n",
  90. processor_info->frequency);
  91. }
  92. printf(" (or something like that)\n");
  93. printf("Features : 0x%x\n", processor_info->features);
  94. }