os_emul.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* This file is part of the program psim.
  2. Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #ifndef _OS_EMUL_C_
  15. #define _OS_EMUL_C_
  16. #include "cpu.h"
  17. #include "idecode.h"
  18. #include "os_emul.h"
  19. #include "emul_generic.h"
  20. #include "emul_netbsd.h"
  21. #include "emul_unix.h"
  22. #include "emul_chirp.h"
  23. #include "emul_bugapi.h"
  24. static const os_emul *(os_emulations[]) = {
  25. &emul_chirp,
  26. &emul_bugapi,
  27. &emul_netbsd,
  28. &emul_solaris,
  29. &emul_linux,
  30. 0
  31. };
  32. INLINE_OS_EMUL\
  33. (os_emul *)
  34. os_emul_create(const char *file_name,
  35. device *root)
  36. {
  37. const char *emulation_name = NULL;
  38. bfd *image;
  39. os_emul *chosen_emulation = NULL;
  40. bfd_init(); /* would never hurt */
  41. /* open the file */
  42. image = bfd_openr(file_name, NULL);
  43. if (image == NULL) {
  44. bfd_perror(file_name);
  45. error("nothing loaded\n");
  46. }
  47. /* check it is an executable */
  48. if (!bfd_check_format(image, bfd_object)) {
  49. TRACE(trace_tbd,
  50. ("FIXME - should check more than just bfd_check_format\n"));
  51. TRACE(trace_os_emul,
  52. ("%s not an executable, assumeing a device file\n", file_name));
  53. bfd_close(image);
  54. image = NULL;
  55. }
  56. /* if a device file, load that before trying the emulations on */
  57. if (image == NULL) {
  58. psim_merge_device_file(root, file_name);
  59. }
  60. /* see if the device tree already specifies the required emulation */
  61. if (tree_find_property(root, "/openprom/options/os-emul") != NULL)
  62. emulation_name =
  63. tree_find_string_property(root, "/openprom/options/os-emul");
  64. else
  65. emulation_name = NULL;
  66. /* go through each emulation to see if they reconize it. FIXME -
  67. should have some sort of imported table from a separate file */
  68. {
  69. os_emul_data *emul_data;
  70. const os_emul **possible_emulation;
  71. chosen_emulation = NULL;
  72. for (possible_emulation = os_emulations, emul_data = NULL;
  73. *possible_emulation != NULL && emul_data == NULL;
  74. possible_emulation++) {
  75. emul_data = (*possible_emulation)->create(root,
  76. image,
  77. emulation_name);
  78. if (emul_data != NULL) {
  79. chosen_emulation = ZALLOC(os_emul);
  80. *chosen_emulation = **possible_emulation;
  81. chosen_emulation->data = emul_data;
  82. }
  83. }
  84. }
  85. /* clean up */
  86. if (image != NULL)
  87. bfd_close(image);
  88. return chosen_emulation;
  89. }
  90. INLINE_OS_EMUL\
  91. (void)
  92. os_emul_init(os_emul *emulation,
  93. int nr_cpus)
  94. {
  95. if (emulation != (os_emul*)0)
  96. emulation->init(emulation->data, nr_cpus);
  97. }
  98. INLINE_OS_EMUL\
  99. (void)
  100. os_emul_system_call(cpu *processor,
  101. unsigned_word cia)
  102. {
  103. os_emul *emulation = cpu_os_emulation(processor);
  104. if (emulation != (os_emul*)0 && emulation->system_call != 0)
  105. emulation->system_call(processor, cia, emulation->data);
  106. else
  107. error("System call emulation not available\n");
  108. }
  109. INLINE_OS_EMUL\
  110. (int)
  111. os_emul_instruction_call(cpu *processor,
  112. unsigned_word cia,
  113. unsigned_word ra)
  114. {
  115. os_emul *emulation = cpu_os_emulation(processor);
  116. if (emulation != (os_emul*)0 && emulation->instruction_call != 0)
  117. return emulation->instruction_call(processor, cia, ra, emulation->data);
  118. else
  119. return 0;
  120. }
  121. #endif /* _OS_EMUL_C_ */