traps.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* Lattice Mico32 exception and system call support.
  2. Contributed by Jon Beniston <jon@beniston.com>
  3. Copyright (C) 2009-2015 Free Software Foundation, Inc.
  4. This file is part of GDB.
  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 lm32bf
  16. #define WANT_CPU_LM32BF
  17. #include "sim-main.h"
  18. #include "sim-syscall.h"
  19. #include "lm32-sim.h"
  20. #include "targ-vals.h"
  21. /* Handle invalid instructions. */
  22. SEM_PC
  23. sim_engine_invalid_insn (SIM_CPU * current_cpu, IADDR cia, SEM_PC pc)
  24. {
  25. SIM_DESC sd = CPU_STATE (current_cpu);
  26. sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
  27. return pc;
  28. }
  29. /* Handle divide instructions. */
  30. USI
  31. lm32bf_divu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2)
  32. {
  33. SIM_DESC sd = CPU_STATE (current_cpu);
  34. host_callback *cb = STATE_CALLBACK (sd);
  35. /* Check for divide by zero */
  36. if (GET_H_GR (r1) == 0)
  37. {
  38. if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
  39. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE);
  40. else
  41. {
  42. /* Save PC in exception address register. */
  43. SET_H_GR (30, pc);
  44. /* Save and clear interrupt enable. */
  45. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
  46. /* Branch to divide by zero exception handler. */
  47. return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DIVIDE_BY_ZERO * 32;
  48. }
  49. }
  50. else
  51. {
  52. SET_H_GR (r2, (USI) GET_H_GR (r0) / (USI) GET_H_GR (r1));
  53. return pc + 4;
  54. }
  55. }
  56. USI
  57. lm32bf_modu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2)
  58. {
  59. SIM_DESC sd = CPU_STATE (current_cpu);
  60. host_callback *cb = STATE_CALLBACK (sd);
  61. /* Check for divide by zero. */
  62. if (GET_H_GR (r1) == 0)
  63. {
  64. if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
  65. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE);
  66. else
  67. {
  68. /* Save PC in exception address register. */
  69. SET_H_GR (30, pc);
  70. /* Save and clear interrupt enable. */
  71. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
  72. /* Branch to divide by zero exception handler. */
  73. return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DIVIDE_BY_ZERO * 32;
  74. }
  75. }
  76. else
  77. {
  78. SET_H_GR (r2, (USI) GET_H_GR (r0) % (USI) GET_H_GR (r1));
  79. return pc + 4;
  80. }
  81. }
  82. /* Handle break instructions. */
  83. USI
  84. lm32bf_break_insn (SIM_CPU * current_cpu, IADDR pc)
  85. {
  86. SIM_DESC sd = CPU_STATE (current_cpu);
  87. host_callback *cb = STATE_CALLBACK (sd);
  88. /* Breakpoint. */
  89. if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
  90. {
  91. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
  92. return pc;
  93. }
  94. else
  95. {
  96. /* Save PC in breakpoint address register. */
  97. SET_H_GR (31, pc);
  98. /* Save and clear interrupt enable. */
  99. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 2);
  100. /* Branch to breakpoint exception handler. */
  101. return GET_H_CSR (LM32_CSR_DEBA) + LM32_EID_BREAKPOINT * 32;
  102. }
  103. }
  104. /* Handle scall instructions. */
  105. USI
  106. lm32bf_scall_insn (SIM_CPU * current_cpu, IADDR pc)
  107. {
  108. SIM_DESC sd = CPU_STATE (current_cpu);
  109. host_callback *cb = STATE_CALLBACK (sd);
  110. if ((STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
  111. || (GET_H_GR (8) == TARGET_SYS_exit))
  112. {
  113. /* Delegate system call to host O/S. */
  114. long result, result2;
  115. int errcode;
  116. /* Perform the system call. */
  117. sim_syscall_multi (current_cpu, GET_H_GR (8), GET_H_GR (1), GET_H_GR (2),
  118. GET_H_GR (3), GET_H_GR (4), &result, &result2,
  119. &errcode);
  120. /* Store the return value in the CPU's registers. */
  121. SET_H_GR (1, result);
  122. SET_H_GR (2, result2);
  123. SET_H_GR (3, errcode);
  124. /* Skip over scall instruction. */
  125. return pc + 4;
  126. }
  127. else
  128. {
  129. /* Save PC in exception address register. */
  130. SET_H_GR (30, pc);
  131. /* Save and clear interrupt enable */
  132. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
  133. /* Branch to system call exception handler. */
  134. return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_SYSTEM_CALL * 32;
  135. }
  136. }
  137. /* Handle b instructions. */
  138. USI
  139. lm32bf_b_insn (SIM_CPU * current_cpu, USI r0, USI f_r0)
  140. {
  141. SIM_DESC sd = CPU_STATE (current_cpu);
  142. host_callback *cb = STATE_CALLBACK (sd);
  143. /* Restore interrupt enable. */
  144. if (f_r0 == 30)
  145. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 2) >> 1);
  146. else if (f_r0 == 31)
  147. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 4) >> 2);
  148. return r0;
  149. }
  150. /* Handle wcsr instructions. */
  151. void
  152. lm32bf_wcsr_insn (SIM_CPU * current_cpu, USI f_csr, USI r1)
  153. {
  154. SIM_DESC sd = CPU_STATE (current_cpu);
  155. host_callback *cb = STATE_CALLBACK (sd);
  156. /* Writing a 1 to IP CSR clears a bit, writing 0 has no effect. */
  157. if (f_csr == LM32_CSR_IP)
  158. SET_H_CSR (f_csr, GET_H_CSR (f_csr) & ~r1);
  159. else
  160. SET_H_CSR (f_csr, r1);
  161. }
  162. /* Handle signals. */
  163. void
  164. lm32_core_signal (SIM_DESC sd,
  165. sim_cpu * cpu,
  166. sim_cia cia,
  167. unsigned map,
  168. int nr_bytes,
  169. address_word addr,
  170. transfer_type transfer, sim_core_signals sig)
  171. {
  172. const char *copy = (transfer == read_transfer ? "read" : "write");
  173. address_word ip = CIA_ADDR (cia);
  174. SIM_CPU *current_cpu = cpu;
  175. switch (sig)
  176. {
  177. case sim_core_unmapped_signal:
  178. sim_io_eprintf (sd,
  179. "core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
  180. nr_bytes, copy, (unsigned long) addr,
  181. (unsigned long) ip);
  182. SET_H_GR (30, ip);
  183. /* Save and clear interrupt enable. */
  184. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
  185. CPU_PC_SET (cpu, GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DATA_BUS_ERROR * 32);
  186. sim_engine_halt (sd, cpu, NULL, LM32_EID_DATA_BUS_ERROR * 32,
  187. sim_stopped, SIM_SIGSEGV);
  188. break;
  189. case sim_core_unaligned_signal:
  190. sim_io_eprintf (sd,
  191. "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
  192. nr_bytes, copy, (unsigned long) addr,
  193. (unsigned long) ip);
  194. SET_H_GR (30, ip);
  195. /* Save and clear interrupt enable. */
  196. SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
  197. CPU_PC_SET (cpu, GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DATA_BUS_ERROR * 32);
  198. sim_engine_halt (sd, cpu, NULL, LM32_EID_DATA_BUS_ERROR * 32,
  199. sim_stopped, SIM_SIGBUS);
  200. break;
  201. default:
  202. sim_engine_abort (sd, cpu, cia,
  203. "sim_core_signal - internal error - bad switch");
  204. }
  205. }