op_helper.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <assert.h>
  2. #include "cpu.h"
  3. #include "helper.h"
  4. #include "qemu/host-utils.h"
  5. #include "hw/lm32/lm32_pic.h"
  6. #include "hw/char/lm32_juart.h"
  7. #include "exec/softmmu_exec.h"
  8. #ifndef CONFIG_USER_ONLY
  9. #include "sysemu/sysemu.h"
  10. #endif
  11. #if !defined(CONFIG_USER_ONLY)
  12. #define MMUSUFFIX _mmu
  13. #define SHIFT 0
  14. #include "exec/softmmu_template.h"
  15. #define SHIFT 1
  16. #include "exec/softmmu_template.h"
  17. #define SHIFT 2
  18. #include "exec/softmmu_template.h"
  19. #define SHIFT 3
  20. #include "exec/softmmu_template.h"
  21. void raise_exception(CPULM32State *env, int index)
  22. {
  23. CPUState *cs = CPU(lm32_env_get_cpu(env));
  24. cs->exception_index = index;
  25. cpu_loop_exit(cs);
  26. }
  27. void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
  28. {
  29. raise_exception(env, index);
  30. }
  31. void HELPER(hlt)(CPULM32State *env)
  32. {
  33. CPUState *cs = CPU(lm32_env_get_cpu(env));
  34. cs->halted = 1;
  35. cs->exception_index = EXCP_HLT;
  36. cpu_loop_exit(cs);
  37. }
  38. void HELPER(ill)(CPULM32State *env)
  39. {
  40. #ifndef CONFIG_USER_ONLY
  41. CPUState *cs = CPU(lm32_env_get_cpu(env));
  42. fprintf(stderr, "VM paused due to illegal instruction. "
  43. "Connect a debugger or switch to the monitor console "
  44. "to find out more.\n");
  45. qemu_system_vmstop_request(RUN_STATE_PAUSED);
  46. cs->halted = 1;
  47. raise_exception(env, EXCP_HALTED);
  48. #endif
  49. }
  50. void HELPER(wcsr_bp)(CPULM32State *env, uint32_t bp, uint32_t idx)
  51. {
  52. uint32_t addr = bp & ~1;
  53. assert(idx < 4);
  54. env->bp[idx] = bp;
  55. lm32_breakpoint_remove(env, idx);
  56. if (bp & 1) {
  57. lm32_breakpoint_insert(env, idx, addr);
  58. }
  59. }
  60. void HELPER(wcsr_wp)(CPULM32State *env, uint32_t wp, uint32_t idx)
  61. {
  62. lm32_wp_t wp_type;
  63. assert(idx < 4);
  64. env->wp[idx] = wp;
  65. wp_type = lm32_wp_type(env->dc, idx);
  66. lm32_watchpoint_remove(env, idx);
  67. if (wp_type != LM32_WP_DISABLED) {
  68. lm32_watchpoint_insert(env, idx, wp, wp_type);
  69. }
  70. }
  71. void HELPER(wcsr_dc)(CPULM32State *env, uint32_t dc)
  72. {
  73. uint32_t old_dc;
  74. int i;
  75. lm32_wp_t old_type;
  76. lm32_wp_t new_type;
  77. old_dc = env->dc;
  78. env->dc = dc;
  79. for (i = 0; i < 4; i++) {
  80. old_type = lm32_wp_type(old_dc, i);
  81. new_type = lm32_wp_type(dc, i);
  82. if (old_type != new_type) {
  83. lm32_watchpoint_remove(env, i);
  84. if (new_type != LM32_WP_DISABLED) {
  85. lm32_watchpoint_insert(env, i, env->wp[i], new_type);
  86. }
  87. }
  88. }
  89. }
  90. void HELPER(wcsr_im)(CPULM32State *env, uint32_t im)
  91. {
  92. lm32_pic_set_im(env->pic_state, im);
  93. }
  94. void HELPER(wcsr_ip)(CPULM32State *env, uint32_t im)
  95. {
  96. lm32_pic_set_ip(env->pic_state, im);
  97. }
  98. void HELPER(wcsr_jtx)(CPULM32State *env, uint32_t jtx)
  99. {
  100. lm32_juart_set_jtx(env->juart_state, jtx);
  101. }
  102. void HELPER(wcsr_jrx)(CPULM32State *env, uint32_t jrx)
  103. {
  104. lm32_juart_set_jrx(env->juart_state, jrx);
  105. }
  106. uint32_t HELPER(rcsr_im)(CPULM32State *env)
  107. {
  108. return lm32_pic_get_im(env->pic_state);
  109. }
  110. uint32_t HELPER(rcsr_ip)(CPULM32State *env)
  111. {
  112. return lm32_pic_get_ip(env->pic_state);
  113. }
  114. uint32_t HELPER(rcsr_jtx)(CPULM32State *env)
  115. {
  116. return lm32_juart_get_jtx(env->juart_state);
  117. }
  118. uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
  119. {
  120. return lm32_juart_get_jrx(env->juart_state);
  121. }
  122. /* Try to fill the TLB and return an exception if error. If retaddr is
  123. * NULL, it means that the function was called in C code (i.e. not
  124. * from generated code or from helper.c)
  125. */
  126. void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
  127. uintptr_t retaddr)
  128. {
  129. int ret;
  130. ret = lm32_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
  131. if (unlikely(ret)) {
  132. if (retaddr) {
  133. /* now we have a real cpu fault */
  134. cpu_restore_state(cs, retaddr);
  135. }
  136. cpu_loop_exit(cs);
  137. }
  138. }
  139. #endif