iq2000.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* IQ2000 simulator support code
  2. Copyright (C) 2000-2022 Free Software Foundation, Inc.
  3. Contributed by Cygnus Support.
  4. This file is part of the GNU simulators.
  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. /* This must come before any other includes. */
  16. #include "defs.h"
  17. #define WANT_CPU
  18. #define WANT_CPU_IQ2000BF
  19. #include "sim-main.h"
  20. #include "sim-signal.h"
  21. #include "cgen-mem.h"
  22. #include "cgen-ops.h"
  23. #include "target-newlib-syscall.h"
  24. #include <stdlib.h>
  25. enum
  26. {
  27. GPR0_REGNUM = 0,
  28. NR_GPR = 32,
  29. PC_REGNUM = 32
  30. };
  31. /* Read a null terminated string from memory, return in a buffer */
  32. static char *
  33. fetch_str (SIM_CPU *current_cpu, PCADDR pc, DI addr)
  34. {
  35. char *buf;
  36. int nr = 0;
  37. while (sim_core_read_1 (current_cpu,
  38. pc, read_map, CPU2DATA(addr + nr)) != 0)
  39. nr++;
  40. buf = NZALLOC (char, nr + 1);
  41. sim_read (CPU_STATE (current_cpu), CPU2DATA(addr), buf, nr);
  42. return buf;
  43. }
  44. void
  45. do_syscall (SIM_CPU *current_cpu, PCADDR pc)
  46. {
  47. #if 0
  48. int syscall = H2T_4 (iq2000bf_h_gr_get (current_cpu, 11));
  49. #endif
  50. int syscall_function = iq2000bf_h_gr_get (current_cpu, 4);
  51. int i;
  52. char *buf;
  53. int PARM1 = iq2000bf_h_gr_get (current_cpu, 5);
  54. int PARM2 = iq2000bf_h_gr_get (current_cpu, 6);
  55. int PARM3 = iq2000bf_h_gr_get (current_cpu, 7);
  56. const int ret_reg = 2;
  57. switch (syscall_function)
  58. {
  59. case 0:
  60. switch (H2T_4 (iq2000bf_h_gr_get (current_cpu, 11)))
  61. {
  62. case 0:
  63. /* Pass. */
  64. puts ("pass");
  65. exit (0);
  66. case 1:
  67. /* Fail. */
  68. puts ("fail");
  69. exit (1);
  70. }
  71. case TARGET_NEWLIB_SYS_write:
  72. buf = zalloc (PARM3);
  73. sim_read (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
  74. SET_H_GR (ret_reg,
  75. sim_io_write (CPU_STATE (current_cpu),
  76. PARM1, buf, PARM3));
  77. free (buf);
  78. break;
  79. case TARGET_NEWLIB_SYS_lseek:
  80. SET_H_GR (ret_reg,
  81. sim_io_lseek (CPU_STATE (current_cpu),
  82. PARM1, PARM2, PARM3));
  83. break;
  84. case TARGET_NEWLIB_SYS_exit:
  85. sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
  86. NULL, pc, sim_exited, PARM1);
  87. break;
  88. case TARGET_NEWLIB_SYS_read:
  89. buf = zalloc (PARM3);
  90. SET_H_GR (ret_reg,
  91. sim_io_read (CPU_STATE (current_cpu),
  92. PARM1, buf, PARM3));
  93. sim_write (CPU_STATE (current_cpu), CPU2DATA(PARM2), buf, PARM3);
  94. free (buf);
  95. break;
  96. case TARGET_NEWLIB_SYS_open:
  97. buf = fetch_str (current_cpu, pc, PARM1);
  98. SET_H_GR (ret_reg,
  99. sim_io_open (CPU_STATE (current_cpu),
  100. buf, PARM2));
  101. free (buf);
  102. break;
  103. case TARGET_NEWLIB_SYS_close:
  104. SET_H_GR (ret_reg,
  105. sim_io_close (CPU_STATE (current_cpu), PARM1));
  106. break;
  107. case TARGET_NEWLIB_SYS_time:
  108. SET_H_GR (ret_reg, time (0));
  109. break;
  110. default:
  111. SET_H_GR (ret_reg, -1);
  112. }
  113. }
  114. void
  115. do_break (SIM_CPU *current_cpu, PCADDR pc)
  116. {
  117. SIM_DESC sd = CPU_STATE (current_cpu);
  118. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
  119. }
  120. /* The semantic code invokes this for invalid (unrecognized) instructions. */
  121. SEM_PC
  122. sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
  123. {
  124. SIM_DESC sd = CPU_STATE (current_cpu);
  125. sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
  126. return vpc;
  127. }
  128. /* Process an address exception. */
  129. void
  130. iq2000_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
  131. unsigned int map, int nr_bytes, address_word addr,
  132. transfer_type transfer, sim_core_signals sig)
  133. {
  134. sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
  135. transfer, sig);
  136. }
  137. /* Initialize cycle counting for an insn.
  138. FIRST_P is non-zero if this is the first insn in a set of parallel
  139. insns. */
  140. void
  141. iq2000bf_model_insn_before (SIM_CPU *cpu, int first_p)
  142. {
  143. /* Do nothing. */
  144. }
  145. /* Record the cycles computed for an insn.
  146. LAST_P is non-zero if this is the last insn in a set of parallel insns,
  147. and we update the total cycle count.
  148. CYCLES is the cycle count of the insn. */
  149. void
  150. iq2000bf_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
  151. {
  152. /* Do nothing. */
  153. }
  154. int
  155. iq2000bf_model_iq2000_u_exec (SIM_CPU *cpu, const IDESC *idesc,
  156. int unit_num, int referenced)
  157. {
  158. return idesc->timing->units[unit_num].done;
  159. }
  160. PCADDR
  161. get_h_pc (SIM_CPU *cpu)
  162. {
  163. return CPU_CGEN_HW(cpu)->h_pc;
  164. }
  165. void
  166. set_h_pc (SIM_CPU *cpu, PCADDR addr)
  167. {
  168. CPU_CGEN_HW(cpu)->h_pc = addr | IQ2000_INSN_MASK;
  169. }
  170. int
  171. iq2000bf_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
  172. {
  173. if (nr >= GPR0_REGNUM
  174. && nr < (GPR0_REGNUM + NR_GPR)
  175. && len == 4)
  176. {
  177. *((uint32_t*)buf) =
  178. H2T_4 (iq2000bf_h_gr_get (cpu, nr - GPR0_REGNUM));
  179. return 4;
  180. }
  181. else if (nr == PC_REGNUM
  182. && len == 4)
  183. {
  184. *((uint32_t*)buf) = H2T_4 (get_h_pc (cpu));
  185. return 4;
  186. }
  187. else
  188. return 0;
  189. }
  190. int
  191. iq2000bf_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
  192. {
  193. if (nr >= GPR0_REGNUM
  194. && nr < (GPR0_REGNUM + NR_GPR)
  195. && len == 4)
  196. {
  197. iq2000bf_h_gr_set (cpu, nr - GPR0_REGNUM, T2H_4 (*((uint32_t*)buf)));
  198. return 4;
  199. }
  200. else if (nr == PC_REGNUM
  201. && len == 4)
  202. {
  203. set_h_pc (cpu, T2H_4 (*((uint32_t*)buf)));
  204. return 4;
  205. }
  206. else
  207. return 0;
  208. }