]> git.proxmox.com Git - mirror_qemu.git/blob - bsd-user/arm/target_arch_cpu.h
hw/display/artist: Fix draw_line() artefacts
[mirror_qemu.git] / bsd-user / arm / target_arch_cpu.h
1 /*
2 * arm cpu init and loop
3 *
4 * Copyright (c) 2013 Stacey D. Son
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef _TARGET_ARCH_CPU_H_
21 #define _TARGET_ARCH_CPU_H_
22
23 #include "target_arch.h"
24
25 #define TARGET_DEFAULT_CPU_MODEL "any"
26
27 static inline void target_cpu_init(CPUARMState *env,
28 struct target_pt_regs *regs)
29 {
30 int i;
31
32 cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
33 CPSRWriteByInstr);
34 for (i = 0; i < 16; i++) {
35 env->regs[i] = regs->uregs[i];
36 }
37 }
38
39 static inline void target_cpu_loop(CPUARMState *env)
40 {
41 int trapnr;
42 target_siginfo_t info;
43 unsigned int n;
44 CPUState *cs = env_cpu(env);
45
46 for (;;) {
47 cpu_exec_start(cs);
48 trapnr = cpu_exec(cs);
49 cpu_exec_end(cs);
50 process_queued_cpu_work(cs);
51 switch (trapnr) {
52 case EXCP_UDEF:
53 {
54 /* See arm/arm/undefined.c undefinedinstruction(); */
55 info.si_addr = env->regs[15];
56
57 /* illegal instruction */
58 info.si_signo = TARGET_SIGILL;
59 info.si_errno = 0;
60 info.si_code = TARGET_ILL_ILLOPC;
61 queue_signal(env, info.si_signo, &info);
62
63 /* TODO: What about instruction emulation? */
64 }
65 break;
66 case EXCP_SWI:
67 case EXCP_BKPT:
68 {
69 /*
70 * system call
71 * See arm/arm/trap.c cpu_fetch_syscall_args()
72 */
73 if (trapnr == EXCP_BKPT) {
74 if (env->thumb) {
75 env->regs[15] += 2;
76 } else {
77 env->regs[15] += 4;
78 }
79 }
80 n = env->regs[7];
81 if (bsd_type == target_freebsd) {
82 int ret;
83 abi_ulong params = get_sp_from_cpustate(env);
84 int32_t syscall_nr = n;
85 int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
86
87 /* See arm/arm/trap.c cpu_fetch_syscall_args() */
88 if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
89 syscall_nr = env->regs[0];
90 arg1 = env->regs[1];
91 arg2 = env->regs[2];
92 arg3 = env->regs[3];
93 get_user_s32(arg4, params);
94 params += sizeof(int32_t);
95 get_user_s32(arg5, params);
96 params += sizeof(int32_t);
97 get_user_s32(arg6, params);
98 params += sizeof(int32_t);
99 get_user_s32(arg7, params);
100 arg8 = 0;
101 } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
102 syscall_nr = env->regs[0];
103 arg1 = env->regs[2];
104 arg2 = env->regs[3];
105 get_user_s32(arg3, params);
106 params += sizeof(int32_t);
107 get_user_s32(arg4, params);
108 params += sizeof(int32_t);
109 get_user_s32(arg5, params);
110 params += sizeof(int32_t);
111 get_user_s32(arg6, params);
112 arg7 = 0;
113 arg8 = 0;
114 } else {
115 arg1 = env->regs[0];
116 arg2 = env->regs[1];
117 arg3 = env->regs[2];
118 arg4 = env->regs[3];
119 get_user_s32(arg5, params);
120 params += sizeof(int32_t);
121 get_user_s32(arg6, params);
122 params += sizeof(int32_t);
123 get_user_s32(arg7, params);
124 params += sizeof(int32_t);
125 get_user_s32(arg8, params);
126 }
127 ret = do_freebsd_syscall(env, syscall_nr, arg1, arg2, arg3,
128 arg4, arg5, arg6, arg7, arg8);
129 /*
130 * Compare to arm/arm/vm_machdep.c
131 * cpu_set_syscall_retval()
132 */
133 if (-TARGET_EJUSTRETURN == ret) {
134 /*
135 * Returning from a successful sigreturn syscall.
136 * Avoid clobbering register state.
137 */
138 break;
139 }
140 if (-TARGET_ERESTART == ret) {
141 env->regs[15] -= env->thumb ? 2 : 4;
142 break;
143 }
144 if ((unsigned int)ret >= (unsigned int)(-515)) {
145 ret = -ret;
146 cpsr_write(env, CPSR_C, CPSR_C, CPSRWriteByInstr);
147 env->regs[0] = ret;
148 } else {
149 cpsr_write(env, 0, CPSR_C, CPSRWriteByInstr);
150 env->regs[0] = ret; /* XXX need to handle lseek()? */
151 /* env->regs[1] = 0; */
152 }
153 } else {
154 fprintf(stderr, "qemu: bsd_type (= %d) syscall "
155 "not supported\n", bsd_type);
156 }
157 }
158 break;
159 case EXCP_INTERRUPT:
160 /* just indicate that signals should be handled asap */
161 break;
162 case EXCP_PREFETCH_ABORT:
163 /* See arm/arm/trap.c prefetch_abort_handler() */
164 case EXCP_DATA_ABORT:
165 /* See arm/arm/trap.c data_abort_handler() */
166 info.si_signo = TARGET_SIGSEGV;
167 info.si_errno = 0;
168 /* XXX: check env->error_code */
169 info.si_code = 0;
170 info.si_addr = env->exception.vaddress;
171 queue_signal(env, info.si_signo, &info);
172 break;
173 case EXCP_DEBUG:
174 {
175
176 info.si_signo = TARGET_SIGTRAP;
177 info.si_errno = 0;
178 info.si_code = TARGET_TRAP_BRKPT;
179 info.si_addr = env->exception.vaddress;
180 queue_signal(env, info.si_signo, &info);
181 }
182 break;
183 case EXCP_ATOMIC:
184 cpu_exec_step_atomic(cs);
185 break;
186 case EXCP_YIELD:
187 /* nothing to do here for user-mode, just resume guest code */
188 break;
189 default:
190 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
191 trapnr);
192 cpu_dump_state(cs, stderr, 0);
193 abort();
194 } /* switch() */
195 process_pending_signals(env);
196 } /* for (;;) */
197 }
198
199 static inline void target_cpu_clone_regs(CPUARMState *env, target_ulong newsp)
200 {
201 if (newsp) {
202 env->regs[13] = newsp;
203 }
204 env->regs[0] = 0;
205 }
206
207 static inline void target_cpu_reset(CPUArchState *cpu)
208 {
209 }
210
211 #endif /* !_TARGET_ARCH_CPU_H */