]>
Commit | Line | Data |
---|---|---|
ea99dde1 | 1 | #include "qemu/osdep.h" |
3e457172 | 2 | #include "cpu.h" |
2ef6175a | 3 | #include "exec/helper-proto.h" |
1de7afc9 | 4 | #include "qemu/host-utils.h" |
143e8951 | 5 | |
0d09e41a | 6 | #include "hw/lm32/lm32_pic.h" |
0ee10242 | 7 | #include "hw/char/lm32_juart.h" |
143e8951 | 8 | |
63c91552 | 9 | #include "exec/exec-all.h" |
f08b6170 | 10 | #include "exec/cpu_ldst.h" |
b1669e5e | 11 | |
667ff961 MW |
12 | #ifndef CONFIG_USER_ONLY |
13 | #include "sysemu/sysemu.h" | |
14 | #endif | |
15 | ||
143e8951 | 16 | #if !defined(CONFIG_USER_ONLY) |
3dd3a2b9 | 17 | void raise_exception(CPULM32State *env, int index) |
143e8951 | 18 | { |
27103424 AF |
19 | CPUState *cs = CPU(lm32_env_get_cpu(env)); |
20 | ||
21 | cs->exception_index = index; | |
5638d180 | 22 | cpu_loop_exit(cs); |
143e8951 MW |
23 | } |
24 | ||
3dd3a2b9 MW |
25 | void HELPER(raise_exception)(CPULM32State *env, uint32_t index) |
26 | { | |
27 | raise_exception(env, index); | |
28 | } | |
29 | ||
66350755 | 30 | void HELPER(hlt)(CPULM32State *env) |
143e8951 | 31 | { |
259186a7 AF |
32 | CPUState *cs = CPU(lm32_env_get_cpu(env)); |
33 | ||
34 | cs->halted = 1; | |
27103424 | 35 | cs->exception_index = EXCP_HLT; |
5638d180 | 36 | cpu_loop_exit(cs); |
143e8951 MW |
37 | } |
38 | ||
667ff961 MW |
39 | void 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"); | |
74892d24 | 46 | vm_stop(RUN_STATE_PAUSED); |
667ff961 MW |
47 | cs->halted = 1; |
48 | raise_exception(env, EXCP_HALTED); | |
49 | #endif | |
50 | } | |
51 | ||
3dd3a2b9 MW |
52 | void 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 | ||
65 | void 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 | ||
80 | void 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 | ||
66350755 | 103 | void HELPER(wcsr_im)(CPULM32State *env, uint32_t im) |
143e8951 MW |
104 | { |
105 | lm32_pic_set_im(env->pic_state, im); | |
106 | } | |
107 | ||
66350755 | 108 | void HELPER(wcsr_ip)(CPULM32State *env, uint32_t im) |
143e8951 MW |
109 | { |
110 | lm32_pic_set_ip(env->pic_state, im); | |
111 | } | |
112 | ||
66350755 | 113 | void HELPER(wcsr_jtx)(CPULM32State *env, uint32_t jtx) |
143e8951 MW |
114 | { |
115 | lm32_juart_set_jtx(env->juart_state, jtx); | |
116 | } | |
117 | ||
66350755 | 118 | void HELPER(wcsr_jrx)(CPULM32State *env, uint32_t jrx) |
143e8951 MW |
119 | { |
120 | lm32_juart_set_jrx(env->juart_state, jrx); | |
121 | } | |
122 | ||
66350755 | 123 | uint32_t HELPER(rcsr_im)(CPULM32State *env) |
143e8951 MW |
124 | { |
125 | return lm32_pic_get_im(env->pic_state); | |
126 | } | |
127 | ||
66350755 | 128 | uint32_t HELPER(rcsr_ip)(CPULM32State *env) |
143e8951 MW |
129 | { |
130 | return lm32_pic_get_ip(env->pic_state); | |
131 | } | |
132 | ||
66350755 | 133 | uint32_t HELPER(rcsr_jtx)(CPULM32State *env) |
143e8951 MW |
134 | { |
135 | return lm32_juart_get_jtx(env->juart_state); | |
136 | } | |
137 | ||
66350755 | 138 | uint32_t HELPER(rcsr_jrx)(CPULM32State *env) |
143e8951 MW |
139 | { |
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 | |
d5a11fef AF |
144 | * NULL, it means that the function was called in C code (i.e. not |
145 | * from generated code or from helper.c) | |
146 | */ | |
b35399bb SS |
147 | void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, |
148 | int mmu_idx, uintptr_t retaddr) | |
143e8951 | 149 | { |
143e8951 MW |
150 | int ret; |
151 | ||
b35399bb | 152 | ret = lm32_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); |
143e8951 MW |
153 | if (unlikely(ret)) { |
154 | if (retaddr) { | |
155 | /* now we have a real cpu fault */ | |
3f38f309 | 156 | cpu_restore_state(cs, retaddr); |
143e8951 | 157 | } |
5638d180 | 158 | cpu_loop_exit(cs); |
143e8951 | 159 | } |
143e8951 MW |
160 | } |
161 | #endif | |
162 |