iq2000.c 5.9 KB

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