1 #include "qemu/osdep.h"
3 #include "exec/helper-proto.h"
4 #include "qemu/host-utils.h"
6 #include "hw/lm32/lm32_pic.h"
7 #include "hw/char/lm32_juart.h"
9 #include "exec/exec-all.h"
10 #include "exec/cpu_ldst.h"
12 #ifndef CONFIG_USER_ONLY
13 #include "sysemu/sysemu.h"
16 #if !defined(CONFIG_USER_ONLY)
17 void raise_exception(CPULM32State
*env
, int index
)
19 CPUState
*cs
= CPU(lm32_env_get_cpu(env
));
21 cs
->exception_index
= index
;
25 void HELPER(raise_exception
)(CPULM32State
*env
, uint32_t index
)
27 raise_exception(env
, index
);
30 void HELPER(hlt
)(CPULM32State
*env
)
32 CPUState
*cs
= CPU(lm32_env_get_cpu(env
));
35 cs
->exception_index
= EXCP_HLT
;
39 void HELPER(ill
)(CPULM32State
*env
)
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");
46 vm_stop(RUN_STATE_PAUSED
);
48 raise_exception(env
, EXCP_HALTED
);
52 void HELPER(wcsr_bp
)(CPULM32State
*env
, uint32_t bp
, uint32_t idx
)
54 uint32_t addr
= bp
& ~1;
59 lm32_breakpoint_remove(env
, idx
);
61 lm32_breakpoint_insert(env
, idx
, addr
);
65 void HELPER(wcsr_wp
)(CPULM32State
*env
, uint32_t wp
, uint32_t idx
)
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
);
80 void HELPER(wcsr_dc
)(CPULM32State
*env
, uint32_t dc
)
90 for (i
= 0; i
< 4; i
++) {
91 old_type
= lm32_wp_type(old_dc
, i
);
92 new_type
= lm32_wp_type(dc
, i
);
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
);
103 void HELPER(wcsr_im
)(CPULM32State
*env
, uint32_t im
)
105 qemu_mutex_lock_iothread();
106 lm32_pic_set_im(env
->pic_state
, im
);
107 qemu_mutex_unlock_iothread();
110 void HELPER(wcsr_ip
)(CPULM32State
*env
, uint32_t im
)
112 qemu_mutex_lock_iothread();
113 lm32_pic_set_ip(env
->pic_state
, im
);
114 qemu_mutex_unlock_iothread();
117 void HELPER(wcsr_jtx
)(CPULM32State
*env
, uint32_t jtx
)
119 lm32_juart_set_jtx(env
->juart_state
, jtx
);
122 void HELPER(wcsr_jrx
)(CPULM32State
*env
, uint32_t jrx
)
124 lm32_juart_set_jrx(env
->juart_state
, jrx
);
127 uint32_t HELPER(rcsr_im
)(CPULM32State
*env
)
129 return lm32_pic_get_im(env
->pic_state
);
132 uint32_t HELPER(rcsr_ip
)(CPULM32State
*env
)
134 return lm32_pic_get_ip(env
->pic_state
);
137 uint32_t HELPER(rcsr_jtx
)(CPULM32State
*env
)
139 return lm32_juart_get_jtx(env
->juart_state
);
142 uint32_t HELPER(rcsr_jrx
)(CPULM32State
*env
)
144 return lm32_juart_get_jrx(env
->juart_state
);
147 /* Try to fill the TLB and return an exception if error. If retaddr is
148 * NULL, it means that the function was called in C code (i.e. not
149 * from generated code or from helper.c)
151 void tlb_fill(CPUState
*cs
, target_ulong addr
, int size
,
152 MMUAccessType access_type
, int mmu_idx
, uintptr_t retaddr
)
156 ret
= lm32_cpu_handle_mmu_fault(cs
, addr
, size
, access_type
, mmu_idx
);
158 /* now we have a real cpu fault */
159 cpu_loop_exit_restore(cs
, retaddr
);