traps.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* m32r exception, interrupt, and trap (EIT) support
  2. Copyright (C) 1998-2015 Free Software Foundation, Inc.
  3. Contributed by Cygnus Solutions.
  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-syscall.h"
  17. #include "targ-vals.h"
  18. #define TRAP_FLUSH_CACHE 12
  19. /* The semantic code invokes this for invalid (unrecognized) instructions. */
  20. SEM_PC
  21. sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC pc)
  22. {
  23. SIM_DESC sd = CPU_STATE (current_cpu);
  24. #if 0
  25. if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
  26. {
  27. h_bsm_set (current_cpu, h_sm_get (current_cpu));
  28. h_bie_set (current_cpu, h_ie_get (current_cpu));
  29. h_bcond_set (current_cpu, h_cond_get (current_cpu));
  30. /* sm not changed */
  31. h_ie_set (current_cpu, 0);
  32. h_cond_set (current_cpu, 0);
  33. h_bpc_set (current_cpu, cia);
  34. sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
  35. EIT_RSVD_INSN_ADDR);
  36. }
  37. else
  38. #endif
  39. sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
  40. return pc;
  41. }
  42. /* Process an address exception. */
  43. void
  44. m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
  45. unsigned int map, int nr_bytes, address_word addr,
  46. transfer_type transfer, sim_core_signals sig)
  47. {
  48. if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
  49. {
  50. m32rbf_h_cr_set (current_cpu, H_CR_BBPC,
  51. m32rbf_h_cr_get (current_cpu, H_CR_BPC));
  52. switch (MACH_NUM (CPU_MACH (current_cpu)))
  53. {
  54. case MACH_M32R:
  55. m32rbf_h_bpsw_set (current_cpu, m32rbf_h_psw_get (current_cpu));
  56. /* sm not changed. */
  57. m32rbf_h_psw_set (current_cpu, m32rbf_h_psw_get (current_cpu) & 0x80);
  58. break;
  59. case MACH_M32RX:
  60. m32rxf_h_bpsw_set (current_cpu, m32rxf_h_psw_get (current_cpu));
  61. /* sm not changed. */
  62. m32rxf_h_psw_set (current_cpu, m32rxf_h_psw_get (current_cpu) & 0x80);
  63. break;
  64. case MACH_M32R2:
  65. m32r2f_h_bpsw_set (current_cpu, m32r2f_h_psw_get (current_cpu));
  66. /* sm not changed. */
  67. m32r2f_h_psw_set (current_cpu, m32r2f_h_psw_get (current_cpu) & 0x80);
  68. break;
  69. default:
  70. abort ();
  71. }
  72. m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia);
  73. sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
  74. EIT_ADDR_EXCP_ADDR);
  75. }
  76. else
  77. sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
  78. transfer, sig);
  79. }
  80. /* Trap support.
  81. The result is the pc address to continue at.
  82. Preprocessing like saving the various registers has already been done. */
  83. USI
  84. m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num)
  85. {
  86. SIM_DESC sd = CPU_STATE (current_cpu);
  87. host_callback *cb = STATE_CALLBACK (sd);
  88. #ifdef SIM_HAVE_BREAKPOINTS
  89. /* Check for breakpoints "owned" by the simulator first, regardless
  90. of --environment. */
  91. if (num == TRAP_BREAKPOINT)
  92. {
  93. /* First try sim-break.c. If it's a breakpoint the simulator "owns"
  94. it doesn't return. Otherwise it returns and let's us try. */
  95. sim_handle_breakpoint (sd, current_cpu, pc);
  96. /* Fall through. */
  97. }
  98. #endif
  99. if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
  100. {
  101. /* The new pc is the trap vector entry.
  102. We assume there's a branch there to some handler.
  103. Use cr5 as EVB (EIT Vector Base) register. */
  104. /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
  105. USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
  106. return new_pc;
  107. }
  108. switch (num)
  109. {
  110. case TRAP_SYSCALL :
  111. {
  112. long result, result2;
  113. int errcode;
  114. sim_syscall_multi (current_cpu,
  115. m32rbf_h_gr_get (current_cpu, 0),
  116. m32rbf_h_gr_get (current_cpu, 1),
  117. m32rbf_h_gr_get (current_cpu, 2),
  118. m32rbf_h_gr_get (current_cpu, 3),
  119. m32rbf_h_gr_get (current_cpu, 4),
  120. &result, &result2, &errcode);
  121. m32rbf_h_gr_set (current_cpu, 2, errcode);
  122. m32rbf_h_gr_set (current_cpu, 0, result);
  123. m32rbf_h_gr_set (current_cpu, 1, result2);
  124. break;
  125. }
  126. case TRAP_BREAKPOINT:
  127. sim_engine_halt (sd, current_cpu, NULL, pc,
  128. sim_stopped, SIM_SIGTRAP);
  129. break;
  130. case TRAP_FLUSH_CACHE:
  131. /* Do nothing. */
  132. break;
  133. default :
  134. {
  135. /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
  136. /* Use cr5 as EVB (EIT Vector Base) register. */
  137. USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
  138. return new_pc;
  139. }
  140. }
  141. /* Fake an "rte" insn. */
  142. /* FIXME: Should duplicate all of rte processing. */
  143. return (pc & -4) + 4;
  144. }