You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dynamic_arm64.c 8.0 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*********************************************************************/
  2. /* Copyright 2009, 2010 The University of Texas at Austin. */
  3. /* All rights reserved. */
  4. /* */
  5. /* Redistribution and use in source and binary forms, with or */
  6. /* without modification, are permitted provided that the following */
  7. /* conditions are met: */
  8. /* */
  9. /* 1. Redistributions of source code must retain the above */
  10. /* copyright notice, this list of conditions and the following */
  11. /* disclaimer. */
  12. /* */
  13. /* 2. Redistributions in binary form must reproduce the above */
  14. /* copyright notice, this list of conditions and the following */
  15. /* disclaimer in the documentation and/or other materials */
  16. /* provided with the distribution. */
  17. /* */
  18. /* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */
  19. /* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */
  20. /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
  21. /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
  22. /* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */
  23. /* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
  24. /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
  25. /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */
  26. /* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
  27. /* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
  28. /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
  29. /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */
  30. /* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
  31. /* POSSIBILITY OF SUCH DAMAGE. */
  32. /* */
  33. /* The views and conclusions contained in the software and */
  34. /* documentation are those of the authors and should not be */
  35. /* interpreted as representing official policies, either expressed */
  36. /* or implied, of The University of Texas at Austin. */
  37. /*********************************************************************/
  38. #include "common.h"
  39. #if (defined OS_LINUX || defined OS_ANDROID)
  40. #include <asm/hwcap.h>
  41. #include <sys/auxv.h>
  42. #endif
  43. extern gotoblas_t gotoblas_ARMV8;
  44. extern gotoblas_t gotoblas_CORTEXA53;
  45. extern gotoblas_t gotoblas_CORTEXA57;
  46. extern gotoblas_t gotoblas_CORTEXA72;
  47. extern gotoblas_t gotoblas_CORTEXA73;
  48. extern gotoblas_t gotoblas_FALKOR;
  49. extern gotoblas_t gotoblas_THUNDERX;
  50. extern gotoblas_t gotoblas_THUNDERX2T99;
  51. extern gotoblas_t gotoblas_TSV110;
  52. extern gotoblas_t gotoblas_EMAG8180;
  53. extern void openblas_warning(int verbose, const char * msg);
  54. #define NUM_CORETYPES 10
  55. /*
  56. * In case asm/hwcap.h is outdated on the build system, make sure
  57. * that HWCAP_CPUID is defined
  58. */
  59. #ifndef HWCAP_CPUID
  60. #define HWCAP_CPUID (1 << 11)
  61. #endif
  62. #define get_cpu_ftr(id, var) ({ \
  63. asm("mrs %0, "#id : "=r" (var)); \
  64. })
  65. static char *corename[] = {
  66. "armv8",
  67. "cortexa53",
  68. "cortexa57",
  69. "cortexa72",
  70. "cortexa73",
  71. "falkor",
  72. "thunderx",
  73. "thunderx2t99",
  74. "tsv110",
  75. "emag8180",
  76. "unknown"
  77. };
  78. char *gotoblas_corename(void) {
  79. if (gotoblas == &gotoblas_ARMV8) return corename[ 0];
  80. if (gotoblas == &gotoblas_CORTEXA53) return corename[ 1];
  81. if (gotoblas == &gotoblas_CORTEXA57) return corename[ 2];
  82. if (gotoblas == &gotoblas_CORTEXA72) return corename[ 3];
  83. if (gotoblas == &gotoblas_CORTEXA73) return corename[ 4];
  84. if (gotoblas == &gotoblas_FALKOR) return corename[ 5];
  85. if (gotoblas == &gotoblas_THUNDERX) return corename[ 6];
  86. if (gotoblas == &gotoblas_THUNDERX2T99) return corename[ 7];
  87. if (gotoblas == &gotoblas_TSV110) return corename[ 8];
  88. if (gotoblas == &gotoblas_EMAG8180) return corename[ 9];
  89. return corename[NUM_CORETYPES];
  90. }
  91. static gotoblas_t *force_coretype(char *coretype) {
  92. int i ;
  93. int found = -1;
  94. char message[128];
  95. for ( i=0 ; i < NUM_CORETYPES; i++)
  96. {
  97. if (!strncasecmp(coretype, corename[i], 20))
  98. {
  99. found = i;
  100. break;
  101. }
  102. }
  103. switch (found)
  104. {
  105. case 0: return (&gotoblas_ARMV8);
  106. case 1: return (&gotoblas_CORTEXA53);
  107. case 2: return (&gotoblas_CORTEXA57);
  108. case 3: return (&gotoblas_CORTEXA72);
  109. case 4: return (&gotoblas_CORTEXA73);
  110. case 5: return (&gotoblas_FALKOR);
  111. case 6: return (&gotoblas_THUNDERX);
  112. case 7: return (&gotoblas_THUNDERX2T99);
  113. case 8: return (&gotoblas_TSV110);
  114. case 9: return (&gotoblas_EMAG8180);
  115. }
  116. snprintf(message, 128, "Core not found: %s\n", coretype);
  117. openblas_warning(1, message);
  118. return NULL;
  119. }
  120. static gotoblas_t *get_coretype(void) {
  121. int implementer, variant, part, arch, revision, midr_el1;
  122. #if (defined OS_LINUX || defined OS_ANDROID)
  123. if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) {
  124. char coremsg[128];
  125. snprintf(coremsg, 128, "Kernel lacks cpuid feature support. Auto detection of core type failed !!!\n");
  126. openblas_warning(1, coremsg);
  127. return NULL;
  128. }
  129. #else
  130. return NULL;
  131. #endif
  132. get_cpu_ftr(MIDR_EL1, midr_el1);
  133. /*
  134. * MIDR_EL1
  135. *
  136. * 31 24 23 20 19 16 15 4 3 0
  137. * -----------------------------------------------------------------
  138. * | Implementer | Variant | Architecture | Part Number | Revision |
  139. * -----------------------------------------------------------------
  140. */
  141. implementer = (midr_el1 >> 24) & 0xFF;
  142. part = (midr_el1 >> 4) & 0xFFF;
  143. switch(implementer)
  144. {
  145. case 0x41: // ARM
  146. switch (part)
  147. {
  148. case 0xd03: // Cortex A53
  149. return &gotoblas_CORTEXA53;
  150. case 0xd07: // Cortex A57
  151. return &gotoblas_CORTEXA57;
  152. case 0xd08: // Cortex A72
  153. return &gotoblas_CORTEXA72;
  154. case 0xd09: // Cortex A73
  155. return &gotoblas_CORTEXA73;
  156. }
  157. break;
  158. case 0x42: // Broadcom
  159. switch (part)
  160. {
  161. case 0x516: // Vulcan
  162. return &gotoblas_THUNDERX2T99;
  163. }
  164. break;
  165. case 0x43: // Cavium
  166. switch (part)
  167. {
  168. case 0x0a1: // ThunderX
  169. return &gotoblas_THUNDERX;
  170. case 0x0af: // ThunderX2
  171. return &gotoblas_THUNDERX2T99;
  172. }
  173. break;
  174. case 0x48: // HiSilicon
  175. switch (part)
  176. {
  177. case 0xd01: // tsv110
  178. return &gotoblas_TSV110;
  179. }
  180. break;
  181. case 0x50: // Ampere
  182. switch (part)
  183. {
  184. case 0x000: // Skylark/EMAG8180
  185. return &gotoblas_EMAG8180;
  186. }
  187. break;
  188. case 0x51: // Qualcomm
  189. switch (part)
  190. {
  191. case 0xc00: // Falkor
  192. return &gotoblas_FALKOR;
  193. }
  194. break;
  195. }
  196. return NULL;
  197. }
  198. void gotoblas_dynamic_init(void) {
  199. char coremsg[128];
  200. char coren[22];
  201. char *p;
  202. if (gotoblas) return;
  203. p = getenv("OPENBLAS_CORETYPE");
  204. if ( p )
  205. {
  206. gotoblas = force_coretype(p);
  207. }
  208. else
  209. {
  210. gotoblas = get_coretype();
  211. }
  212. if (gotoblas == NULL)
  213. {
  214. snprintf(coremsg, 128, "Falling back to generic ARMV8 core\n");
  215. openblas_warning(1, coremsg);
  216. gotoblas = &gotoblas_ARMV8;
  217. }
  218. if (gotoblas && gotoblas->init) {
  219. strncpy(coren, gotoblas_corename(), 20);
  220. sprintf(coremsg, "Core: %s\n", coren);
  221. openblas_warning(2, coremsg);
  222. gotoblas -> init();
  223. } else {
  224. openblas_warning(0, "OpenBLAS : Architecture Initialization failed. No initialization function found.\n");
  225. exit(1);
  226. }
  227. }
  228. void gotoblas_dynamic_quit(void) {
  229. gotoblas = NULL;
  230. }