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