blob: 2177c8ad12df7b07c5f7ab2874400c6911826faa [file] [log] [blame]
Peter Maydellea99dde2016-01-26 18:16:57 +00001#include "qemu/osdep.h"
Blue Swirl3e457172011-07-13 12:44:15 +00002#include "cpu.h"
Richard Henderson2ef61752014-04-07 22:31:41 -07003#include "exec/helper-proto.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +01004#include "qemu/host-utils.h"
Michael Walle143e8952011-02-17 23:45:04 +01005
Paolo Bonzini0d09e412013-02-05 17:06:20 +01006#include "hw/lm32/lm32_pic.h"
Andreas Färber0ee10242013-07-24 22:49:02 +02007#include "hw/char/lm32_juart.h"
Michael Walle143e8952011-02-17 23:45:04 +01008
Paolo Bonzini63c91552016-03-15 13:18:37 +01009#include "exec/exec-all.h"
Paolo Bonzinif08b6172014-03-28 19:42:10 +010010#include "exec/cpu_ldst.h"
Richard Hendersonb1669e52013-08-27 13:03:27 -070011
Michael Walle667ff962013-09-23 20:47:33 +020012#ifndef CONFIG_USER_ONLY
13#include "sysemu/sysemu.h"
14#endif
15
Michael Walle143e8952011-02-17 23:45:04 +010016#if !defined(CONFIG_USER_ONLY)
Michael Walle3dd3a2b2013-09-18 19:10:45 +020017void raise_exception(CPULM32State *env, int index)
Michael Walle143e8952011-02-17 23:45:04 +010018{
Andreas Färber27103422013-08-26 08:31:06 +020019 CPUState *cs = CPU(lm32_env_get_cpu(env));
20
21 cs->exception_index = index;
Andreas Färber5638d182013-08-27 17:52:12 +020022 cpu_loop_exit(cs);
Michael Walle143e8952011-02-17 23:45:04 +010023}
24
Michael Walle3dd3a2b2013-09-18 19:10:45 +020025void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
26{
27 raise_exception(env, index);
28}
29
Michael Walle66350752013-03-03 23:17:48 +010030void HELPER(hlt)(CPULM32State *env)
Michael Walle143e8952011-02-17 23:45:04 +010031{
Andreas Färber259186a2013-01-17 18:51:17 +010032 CPUState *cs = CPU(lm32_env_get_cpu(env));
33
34 cs->halted = 1;
Andreas Färber27103422013-08-26 08:31:06 +020035 cs->exception_index = EXCP_HLT;
Andreas Färber5638d182013-08-27 17:52:12 +020036 cpu_loop_exit(cs);
Michael Walle143e8952011-02-17 23:45:04 +010037}
38
Michael Walle667ff962013-09-23 20:47:33 +020039void HELPER(ill)(CPULM32State *env)
40{
41#ifndef CONFIG_USER_ONLY
42 CPUState *cs = CPU(lm32_env_get_cpu(env));
43 fprintf(stderr, "VM paused due to illegal instruction. "
44 "Connect a debugger or switch to the monitor console "
45 "to find out more.\n");
Paolo Bonzini74892d22014-06-05 14:53:58 +020046 vm_stop(RUN_STATE_PAUSED);
Michael Walle667ff962013-09-23 20:47:33 +020047 cs->halted = 1;
48 raise_exception(env, EXCP_HALTED);
49#endif
50}
51
Michael Walle3dd3a2b2013-09-18 19:10:45 +020052void HELPER(wcsr_bp)(CPULM32State *env, uint32_t bp, uint32_t idx)
53{
54 uint32_t addr = bp & ~1;
55
56 assert(idx < 4);
57
58 env->bp[idx] = bp;
59 lm32_breakpoint_remove(env, idx);
60 if (bp & 1) {
61 lm32_breakpoint_insert(env, idx, addr);
62 }
63}
64
65void HELPER(wcsr_wp)(CPULM32State *env, uint32_t wp, uint32_t idx)
66{
67 lm32_wp_t wp_type;
68
69 assert(idx < 4);
70
71 env->wp[idx] = wp;
72
73 wp_type = lm32_wp_type(env->dc, idx);
74 lm32_watchpoint_remove(env, idx);
75 if (wp_type != LM32_WP_DISABLED) {
76 lm32_watchpoint_insert(env, idx, wp, wp_type);
77 }
78}
79
80void HELPER(wcsr_dc)(CPULM32State *env, uint32_t dc)
81{
82 uint32_t old_dc;
83 int i;
84 lm32_wp_t old_type;
85 lm32_wp_t new_type;
86
87 old_dc = env->dc;
88 env->dc = dc;
89
90 for (i = 0; i < 4; i++) {
91 old_type = lm32_wp_type(old_dc, i);
92 new_type = lm32_wp_type(dc, i);
93
94 if (old_type != new_type) {
95 lm32_watchpoint_remove(env, i);
96 if (new_type != LM32_WP_DISABLED) {
97 lm32_watchpoint_insert(env, i, env->wp[i], new_type);
98 }
99 }
100 }
101}
102
Michael Walle66350752013-03-03 23:17:48 +0100103void HELPER(wcsr_im)(CPULM32State *env, uint32_t im)
Michael Walle143e8952011-02-17 23:45:04 +0100104{
105 lm32_pic_set_im(env->pic_state, im);
106}
107
Michael Walle66350752013-03-03 23:17:48 +0100108void HELPER(wcsr_ip)(CPULM32State *env, uint32_t im)
Michael Walle143e8952011-02-17 23:45:04 +0100109{
110 lm32_pic_set_ip(env->pic_state, im);
111}
112
Michael Walle66350752013-03-03 23:17:48 +0100113void HELPER(wcsr_jtx)(CPULM32State *env, uint32_t jtx)
Michael Walle143e8952011-02-17 23:45:04 +0100114{
115 lm32_juart_set_jtx(env->juart_state, jtx);
116}
117
Michael Walle66350752013-03-03 23:17:48 +0100118void HELPER(wcsr_jrx)(CPULM32State *env, uint32_t jrx)
Michael Walle143e8952011-02-17 23:45:04 +0100119{
120 lm32_juart_set_jrx(env->juart_state, jrx);
121}
122
Michael Walle66350752013-03-03 23:17:48 +0100123uint32_t HELPER(rcsr_im)(CPULM32State *env)
Michael Walle143e8952011-02-17 23:45:04 +0100124{
125 return lm32_pic_get_im(env->pic_state);
126}
127
Michael Walle66350752013-03-03 23:17:48 +0100128uint32_t HELPER(rcsr_ip)(CPULM32State *env)
Michael Walle143e8952011-02-17 23:45:04 +0100129{
130 return lm32_pic_get_ip(env->pic_state);
131}
132
Michael Walle66350752013-03-03 23:17:48 +0100133uint32_t HELPER(rcsr_jtx)(CPULM32State *env)
Michael Walle143e8952011-02-17 23:45:04 +0100134{
135 return lm32_juart_get_jtx(env->juart_state);
136}
137
Michael Walle66350752013-03-03 23:17:48 +0100138uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
Michael Walle143e8952011-02-17 23:45:04 +0100139{
140 return lm32_juart_get_jrx(env->juart_state);
141}
142
143/* Try to fill the TLB and return an exception if error. If retaddr is
Andreas Färberd5a11fe2013-08-27 00:28:06 +0200144 * NULL, it means that the function was called in C code (i.e. not
145 * from generated code or from helper.c)
146 */
Sergey Sorokinb35399b2016-06-14 15:26:17 +0300147void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
148 int mmu_idx, uintptr_t retaddr)
Michael Walle143e8952011-02-17 23:45:04 +0100149{
Michael Walle143e8952011-02-17 23:45:04 +0100150 int ret;
151
Sergey Sorokinb35399b2016-06-14 15:26:17 +0300152 ret = lm32_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
Michael Walle143e8952011-02-17 23:45:04 +0100153 if (unlikely(ret)) {
154 if (retaddr) {
155 /* now we have a real cpu fault */
Andreas Färber3f38f302013-09-01 16:51:34 +0200156 cpu_restore_state(cs, retaddr);
Michael Walle143e8952011-02-17 23:45:04 +0100157 }
Andreas Färber5638d182013-08-27 17:52:12 +0200158 cpu_loop_exit(cs);
Michael Walle143e8952011-02-17 23:45:04 +0100159 }
Michael Walle143e8952011-02-17 23:45:04 +0100160}
161#endif
162