sim-model.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /* Model support.
  2. Copyright (C) 1996-2015 Free Software Foundation, Inc.
  3. Contributed by Cygnus Support.
  4. This file is part of GDB, the GNU debugger.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include "sim-main.h"
  16. #include "sim-model.h"
  17. #include "libiberty.h"
  18. #include "sim-options.h"
  19. #include "sim-io.h"
  20. #include "sim-assert.h"
  21. #include "bfd.h"
  22. static void model_set (sim_cpu *, const MODEL *);
  23. static DECLARE_OPTION_HANDLER (model_option_handler);
  24. static MODULE_INIT_FN sim_model_init;
  25. enum {
  26. OPTION_MODEL = OPTION_START,
  27. OPTION_MODEL_INFO,
  28. };
  29. static const OPTION model_options[] = {
  30. { {"model", required_argument, NULL, OPTION_MODEL},
  31. '\0', "MODEL", "Specify model to simulate",
  32. model_option_handler, NULL },
  33. { {"model-info", no_argument, NULL, OPTION_MODEL_INFO},
  34. '\0', NULL, "List selectable models",
  35. model_option_handler, NULL },
  36. { {"info-model", no_argument, NULL, OPTION_MODEL_INFO},
  37. '\0', NULL, NULL,
  38. model_option_handler, NULL },
  39. { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
  40. };
  41. static SIM_RC
  42. model_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
  43. char *arg, int is_command)
  44. {
  45. switch (opt)
  46. {
  47. case OPTION_MODEL :
  48. {
  49. const MODEL *model = sim_model_lookup (arg);
  50. if (! model)
  51. {
  52. sim_io_eprintf (sd, "unknown model `%s'\n", arg);
  53. return SIM_RC_FAIL;
  54. }
  55. sim_model_set (sd, cpu, model);
  56. break;
  57. }
  58. case OPTION_MODEL_INFO :
  59. {
  60. const MACH **machp;
  61. const MODEL *model;
  62. for (machp = & sim_machs[0]; *machp != NULL; ++machp)
  63. {
  64. sim_io_printf (sd, "Models for architecture `%s':\n",
  65. MACH_NAME (*machp));
  66. for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL;
  67. ++model)
  68. sim_io_printf (sd, " %s", MODEL_NAME (model));
  69. sim_io_printf (sd, "\n");
  70. }
  71. break;
  72. }
  73. }
  74. return SIM_RC_OK;
  75. }
  76. SIM_RC
  77. sim_model_install (SIM_DESC sd)
  78. {
  79. SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  80. sim_add_option_table (sd, NULL, model_options);
  81. sim_module_add_init_fn (sd, sim_model_init);
  82. return SIM_RC_OK;
  83. }
  84. /* Subroutine of sim_model_set to set the model for one cpu. */
  85. static void
  86. model_set (sim_cpu *cpu, const MODEL *model)
  87. {
  88. CPU_MACH (cpu) = MODEL_MACH (model);
  89. CPU_MODEL (cpu) = model;
  90. (* MACH_INIT_CPU (MODEL_MACH (model))) (cpu);
  91. (* MODEL_INIT (model)) (cpu);
  92. }
  93. /* Set the current model of CPU to MODEL.
  94. If CPU is NULL, all cpus are set to MODEL. */
  95. void
  96. sim_model_set (SIM_DESC sd, sim_cpu *cpu, const MODEL *model)
  97. {
  98. if (! cpu)
  99. {
  100. int c;
  101. for (c = 0; c < MAX_NR_PROCESSORS; ++c)
  102. if (STATE_CPU (sd, c))
  103. model_set (STATE_CPU (sd, c), model);
  104. }
  105. else
  106. {
  107. model_set (cpu, model);
  108. }
  109. }
  110. /* Look up model named NAME.
  111. Result is pointer to MODEL entry or NULL if not found. */
  112. const MODEL *
  113. sim_model_lookup (const char *name)
  114. {
  115. const MACH **machp;
  116. const MODEL *model;
  117. for (machp = & sim_machs[0]; *machp != NULL; ++machp)
  118. {
  119. for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL; ++model)
  120. {
  121. if (strcmp (MODEL_NAME (model), name) == 0)
  122. return model;
  123. }
  124. }
  125. return NULL;
  126. }
  127. /* Look up machine named NAME.
  128. Result is pointer to MACH entry or NULL if not found. */
  129. const MACH *
  130. sim_mach_lookup (const char *name)
  131. {
  132. const MACH **machp;
  133. for (machp = & sim_machs[0]; *machp != NULL; ++machp)
  134. {
  135. if (strcmp (MACH_NAME (*machp), name) == 0)
  136. return *machp;
  137. }
  138. return NULL;
  139. }
  140. /* Look up a machine via its bfd name.
  141. Result is pointer to MACH entry or NULL if not found. */
  142. const MACH *
  143. sim_mach_lookup_bfd_name (const char *name)
  144. {
  145. const MACH **machp;
  146. for (machp = & sim_machs[0]; *machp != NULL; ++machp)
  147. {
  148. if (strcmp (MACH_BFD_NAME (*machp), name) == 0)
  149. return *machp;
  150. }
  151. return NULL;
  152. }
  153. /* Initialize model support. */
  154. static SIM_RC
  155. sim_model_init (SIM_DESC sd)
  156. {
  157. SIM_CPU *cpu;
  158. /* If both cpu model and state architecture are set, ensure they're
  159. compatible. If only one is set, set the other. If neither are set,
  160. use the default model. STATE_ARCHITECTURE is the bfd_arch_info data
  161. for the selected "mach" (bfd terminology). */
  162. /* Only check cpu 0. STATE_ARCHITECTURE is for that one only. */
  163. /* ??? At present this only supports homogeneous multiprocessors. */
  164. cpu = STATE_CPU (sd, 0);
  165. if (! STATE_ARCHITECTURE (sd)
  166. && ! CPU_MACH (cpu))
  167. {
  168. /* Set the default model. */
  169. const MODEL *model = sim_model_lookup (WITH_DEFAULT_MODEL);
  170. SIM_ASSERT (model != NULL);
  171. sim_model_set (sd, NULL, model);
  172. }
  173. if (STATE_ARCHITECTURE (sd)
  174. && CPU_MACH (cpu))
  175. {
  176. if (strcmp (STATE_ARCHITECTURE (sd)->printable_name,
  177. MACH_BFD_NAME (CPU_MACH (cpu))) != 0)
  178. {
  179. sim_io_eprintf (sd, "invalid model `%s' for `%s'\n",
  180. MODEL_NAME (CPU_MODEL (cpu)),
  181. STATE_ARCHITECTURE (sd)->printable_name);
  182. return SIM_RC_FAIL;
  183. }
  184. }
  185. else if (STATE_ARCHITECTURE (sd))
  186. {
  187. /* Use the default model for the selected machine.
  188. The default model is the first one in the list. */
  189. const MACH *mach = sim_mach_lookup_bfd_name (STATE_ARCHITECTURE (sd)->printable_name);
  190. if (mach == NULL)
  191. {
  192. sim_io_eprintf (sd, "unsupported machine `%s'\n",
  193. STATE_ARCHITECTURE (sd)->printable_name);
  194. return SIM_RC_FAIL;
  195. }
  196. sim_model_set (sd, NULL, MACH_MODELS (mach));
  197. }
  198. else
  199. {
  200. STATE_ARCHITECTURE (sd) = bfd_scan_arch (MACH_BFD_NAME (CPU_MACH (cpu)));
  201. }
  202. return SIM_RC_OK;
  203. }