diff options
| -rw-r--r-- | Makefile.target | 2 | ||||
| -rwxr-xr-x | configure | 12 | ||||
| -rw-r--r-- | exec-all.h | 33 | ||||
| -rw-r--r-- | exec.c | 6 | ||||
| -rw-r--r-- | fpu/softfloat.c | 12 | ||||
| -rw-r--r-- | main-loop.c | 147 | ||||
| -rw-r--r-- | main-loop.h | 1 | ||||
| -rw-r--r-- | oslib-win32.c | 3 | ||||
| -rw-r--r-- | target-sparc/cpu-qom.h | 75 | ||||
| -rw-r--r-- | target-sparc/cpu.c (renamed from target-sparc/cpu_init.c) | 68 | ||||
| -rw-r--r-- | target-sparc/cpu.h | 1 | ||||
| -rw-r--r-- | translate-all.c | 6 |
12 files changed, 263 insertions, 103 deletions
diff --git a/Makefile.target b/Makefile.target index 999a968abe..14c8fa18fc 100644 --- a/Makefile.target +++ b/Makefile.target @@ -96,7 +96,7 @@ libobj-$(TARGET_ARM) += cpu.o libobj-$(TARGET_S390X) += cpu.o ifeq ($(TARGET_BASE_ARCH), sparc) libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o -libobj-y += cpu_init.o +libobj-y += cpu.o endif libobj-$(TARGET_SPARC) += int32_helper.o libobj-$(TARGET_SPARC64) += int64_helper.o diff --git a/configure b/configure index 4b3adc9bd4..6f850a66c3 100755 --- a/configure +++ b/configure @@ -1993,13 +1993,21 @@ fi ########################################## # glib support probe -if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then + +if test "$mingw32" = yes; then + # g_poll is required in order to integrate with the glib main loop. + glib_req_ver=2.20 +else + glib_req_ver=2.12 +fi +if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1 +then glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null` glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null` LIBS="$glib_libs $LIBS" libs_qga="$glib_libs $libs_qga" else - echo "glib-2.0 required to compile QEMU" + echo "glib-$glib_req_ver required to compile QEMU" exit 1 fi diff --git a/exec-all.h b/exec-all.h index 93a5b22c1c..a6d6519891 100644 --- a/exec-all.h +++ b/exec-all.h @@ -85,7 +85,7 @@ void cpu_gen_init(void); int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb, int *gen_code_size_ptr); int cpu_restore_state(struct TranslationBlock *tb, - CPUArchState *env, unsigned long searched_pc); + CPUArchState *env, uintptr_t searched_pc); void cpu_resume_from_signal(CPUArchState *env1, void *puc); void cpu_io_recompile(CPUArchState *env, void *retaddr); TranslationBlock *tb_gen_code(CPUArchState *env, @@ -93,7 +93,7 @@ TranslationBlock *tb_gen_code(CPUArchState *env, int cflags); void cpu_exec_init(CPUArchState *env); void QEMU_NORETURN cpu_loop_exit(CPUArchState *env1); -int page_unprotect(target_ulong address, unsigned long pc, void *puc); +int page_unprotect(target_ulong address, uintptr_t pc, void *puc); void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, int is_cpu_write_access); void tlb_flush_page(CPUArchState *env, target_ulong addr); @@ -150,7 +150,7 @@ struct TranslationBlock { #ifdef USE_DIRECT_JUMP uint16_t tb_jmp_offset[2]; /* offset of jump instruction */ #else - unsigned long tb_next[2]; /* address of jump generated code */ + uintptr_t tb_next[2]; /* address of jump generated code */ #endif /* list of TBs jumping to this one. This is a circular list using the two least significant bits of the pointers to tell what is @@ -202,14 +202,14 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr); #define tb_set_jmp_target1 ppc_tb_set_jmp_target #elif defined(__i386__) || defined(__x86_64__) -static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) +static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) { /* patch the branch destination */ *(uint32_t *)jmp_addr = addr - (jmp_addr + 4); /* no need to flush icache explicitly */ } #elif defined(__arm__) -static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) +static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) { #if !QEMU_GNUC_PREREQ(4, 1) register unsigned long _beg __asm ("a1"); @@ -237,19 +237,17 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr #endif static inline void tb_set_jmp_target(TranslationBlock *tb, - int n, unsigned long addr) + int n, uintptr_t addr) { - unsigned long offset; - - offset = tb->tb_jmp_offset[n]; - tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr); + uint16_t offset = tb->tb_jmp_offset[n]; + tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr); } #else /* set the jump target */ static inline void tb_set_jmp_target(TranslationBlock *tb, - int n, unsigned long addr) + int n, uintptr_t addr) { tb->tb_next[n] = addr; } @@ -262,15 +260,15 @@ static inline void tb_add_jump(TranslationBlock *tb, int n, /* NOTE: this test is only needed for thread safety */ if (!tb->jmp_next[n]) { /* patch the native jump address */ - tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr); + tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr); /* add in TB jmp circular list */ tb->jmp_next[n] = tb_next->jmp_first; - tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n)); + tb_next->jmp_first = (TranslationBlock *)((uintptr_t)(tb) | (n)); } } -TranslationBlock *tb_find_pc(unsigned long pc_ptr); +TranslationBlock *tb_find_pc(uintptr_t pc_ptr); #include "qemu-lock.h" @@ -288,13 +286,14 @@ extern void *tci_tb_ptr; # define GETPC() tci_tb_ptr # endif #elif defined(__s390__) && !defined(__s390x__) -# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1)) +# define GETPC() \ + ((void *)(((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1)) #elif defined(__arm__) /* Thumb return addresses have the low bit set, so we need to subtract two. This is still safe in ARM mode because instructions are 4 bytes. */ -# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2)) +# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 2)) #else -# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1)) +# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 1)) #endif #if !defined(CONFIG_USER_ONLY) diff --git a/exec.c b/exec.c index 6731ab8c4b..03d3a6b609 100644 --- a/exec.c +++ b/exec.c @@ -1380,7 +1380,7 @@ void tb_link_page(TranslationBlock *tb, /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < tb[1].tc_ptr. Return NULL if not found */ -TranslationBlock *tb_find_pc(unsigned long tc_ptr) +TranslationBlock *tb_find_pc(uintptr_t tc_ptr) { int m_min, m_max, m; unsigned long v; @@ -2502,7 +2502,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags) /* called from signal handler: invalidate the code and unprotect the page. Return TRUE if the fault was successfully handled. */ -int page_unprotect(target_ulong address, unsigned long pc, void *puc) +int page_unprotect(target_ulong address, uintptr_t pc, void *puc) { unsigned int prot; PageDesc *p; @@ -4484,7 +4484,7 @@ void cpu_io_recompile(CPUArchState *env, void *retaddr) target_ulong pc, cs_base; uint64_t flags; - tb = tb_find_pc((unsigned long)retaddr); + tb = tb_find_pc((uintptr_t)retaddr); if (!tb) { cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p", retaddr); diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 81a7d1ae09..d37090ac53 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -117,7 +117,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM) int8 roundingMode; flag roundNearestEven; int8 roundIncrement, roundBits; - int32 z; + int32_t z; roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); @@ -166,7 +166,7 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU { int8 roundingMode; flag roundNearestEven, increment; - int64 z; + int64_t z; roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); @@ -1378,7 +1378,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) flag aSign; int16 aExp, shiftCount; uint32_t aSig; - int32 z; + int32_t z; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); @@ -2762,7 +2762,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM ) flag aSign; int16 aExp, shiftCount; uint64_t aSig, savedASig; - int32 z; + int32_t z; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); @@ -4248,7 +4248,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM ) flag aSign; int32 aExp, shiftCount; uint64_t aSig, savedASig; - int32 z; + int32_t z; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); @@ -5277,7 +5277,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM ) flag aSign; int32 aExp, shiftCount; uint64_t aSig0, aSig1, savedASig; - int32 z; + int32_t z; aSig1 = extractFloat128Frac1( a ); aSig0 = extractFloat128Frac0( a ); diff --git a/main-loop.c b/main-loop.c index db23de0497..7e163f9428 100644 --- a/main-loop.c +++ b/main-loop.c @@ -218,17 +218,19 @@ int main_loop_init(void) return 0; } - +static fd_set rfds, wfds, xfds; +static int nfds; static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */ static int n_poll_fds; static int max_priority; +#ifndef _WIN32 static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds, - fd_set *xfds, struct timeval *tv) + fd_set *xfds, int *cur_timeout) { GMainContext *context = g_main_context_default(); int i; - int timeout = 0, cur_timeout; + int timeout = 0; g_main_context_prepare(context, &max_priority); @@ -253,10 +255,8 @@ static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds, } } - cur_timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 500) / 1000); - if (timeout >= 0 && timeout < cur_timeout) { - tv->tv_sec = timeout / 1000; - tv->tv_usec = (timeout % 1000) * 1000; + if (timeout >= 0 && timeout < *cur_timeout) { + *cur_timeout = timeout; } } @@ -288,7 +288,29 @@ static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds, } } -#ifdef _WIN32 +static int os_host_main_loop_wait(int timeout) +{ + struct timeval tv; + int ret; + + glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout); + + if (timeout > 0) { + qemu_mutex_unlock_iothread(); + } + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); + + if (timeout > 0) { + qemu_mutex_lock_iothread(); + } + + glib_select_poll(&rfds, &wfds, &xfds, (ret < 0)); + return ret; +} +#else /***********************************************************/ /* Polling handling */ @@ -328,6 +350,7 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque) /* Wait objects support */ typedef struct WaitObjects { int num; + int revents[MAXIMUM_WAIT_OBJECTS + 1]; HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1]; void *opaque[MAXIMUM_WAIT_OBJECTS + 1]; @@ -344,6 +367,7 @@ int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) w->events[w->num] = handle; w->func[w->num] = func; w->opaque[w->num] = opaque; + w->revents[w->num] = 0; w->num++; return 0; } @@ -362,6 +386,7 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) w->events[i] = w->events[i + 1]; w->func[i] = w->func[i + 1]; w->opaque[i] = w->opaque[i + 1]; + w->revents[i] = w->revents[i + 1]; } } if (found) { @@ -369,61 +394,76 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) } } -static void os_host_main_loop_wait(int *timeout) +void qemu_fd_register(int fd) { - int ret, ret2, i; + WSAEventSelect(fd, qemu_event_handle, FD_READ | FD_ACCEPT | FD_CLOSE | + FD_CONNECT | FD_WRITE | FD_OOB); +} + +static int os_host_main_loop_wait(int timeout) +{ + GMainContext *context = g_main_context_default(); + int ret, i; PollingEntry *pe; + WaitObjects *w = &wait_objects; + static struct timeval tv0; /* XXX: need to suppress polling by better using win32 events */ ret = 0; for (pe = first_polling_entry; pe != NULL; pe = pe->next) { ret |= pe->func(pe->opaque); } - if (ret == 0) { - int err; - WaitObjects *w = &wait_objects; + if (ret != 0) { + return ret; + } - qemu_mutex_unlock_iothread(); - ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout); - qemu_mutex_lock_iothread(); - if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) { - if (w->func[ret - WAIT_OBJECT_0]) { - w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]); - } + if (nfds >= 0) { + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0); + if (ret != 0) { + timeout = 0; + } + } + + g_main_context_prepare(context, &max_priority); + n_poll_fds = g_main_context_query(context, max_priority, &timeout, + poll_fds, ARRAY_SIZE(poll_fds)); + g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds)); - /* Check for additional signaled events */ - for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) { - /* Check if event is signaled */ - ret2 = WaitForSingleObject(w->events[i], 0); - if (ret2 == WAIT_OBJECT_0) { - if (w->func[i]) { - w->func[i](w->opaque[i]); - } - } else if (ret2 != WAIT_TIMEOUT) { - err = GetLastError(); - fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err); - } + for (i = 0; i < w->num; i++) { + poll_fds[n_poll_fds + i].fd = (DWORD) w->events[i]; + poll_fds[n_poll_fds + i].events = G_IO_IN; + } + + qemu_mutex_unlock_iothread(); + ret = g_poll(poll_fds, n_poll_fds + w->num, timeout); + qemu_mutex_lock_iothread(); + if (ret > 0) { + for (i = 0; i < w->num; i++) { + w->revents[i] = poll_fds[n_poll_fds + i].revents; + } + for (i = 0; i < w->num; i++) { + if (w->revents[i] && w->func[i]) { + w->func[i](w->opaque[i]); } - } else if (ret != WAIT_TIMEOUT) { - err = GetLastError(); - fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err); } } - *timeout = 0; -} -#else -static inline void os_host_main_loop_wait(int *timeout) -{ + if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) { + g_main_context_dispatch(context); + } + + /* If an edge-triggered socket event occurred, select will return a + * positive result on the next iteration. We do not need to do anything + * here. + */ + + return ret; } #endif int main_loop_wait(int nonblocking) { - fd_set rfds, wfds, xfds; - int ret, nfds; - struct timeval tv; - int timeout; + int ret, timeout; if (nonblocking) { timeout = 0; @@ -432,11 +472,6 @@ int main_loop_wait(int nonblocking) qemu_bh_update_timeout(&timeout); } - os_host_main_loop_wait(&timeout); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - /* poll any events */ /* XXX: separate device handlers from system ones */ nfds = -1; @@ -448,19 +483,7 @@ int main_loop_wait(int nonblocking) slirp_select_fill(&nfds, &rfds, &wfds, &xfds); #endif qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds); - glib_select_fill(&nfds, &rfds, &wfds, &xfds, &tv); - - if (timeout > 0) { - qemu_mutex_unlock_iothread(); - } - - ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - - if (timeout > 0) { - qemu_mutex_lock_iothread(); - } - - glib_select_poll(&rfds, &wfds, &xfds, (ret < 0)); + ret = os_host_main_loop_wait(timeout); qemu_iohandler_poll(&rfds, &wfds, &xfds, ret); #ifdef CONFIG_SLIRP slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); diff --git a/main-loop.h b/main-loop.h index 4987041ce7..e743aa0cf6 100644 --- a/main-loop.h +++ b/main-loop.h @@ -359,6 +359,7 @@ void qemu_mutex_unlock_iothread(void); /* internal interfaces */ +void qemu_fd_register(int fd); void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds); void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int rc); diff --git a/oslib-win32.c b/oslib-win32.c index ce3021e6c7..ffbc6d0c9f 100644 --- a/oslib-win32.c +++ b/oslib-win32.c @@ -28,6 +28,7 @@ #include <windows.h> #include "config-host.h" #include "sysemu.h" +#include "main-loop.h" #include "trace.h" #include "qemu_socket.h" @@ -76,6 +77,7 @@ void qemu_vfree(void *ptr) void socket_set_block(int fd) { unsigned long opt = 0; + WSAEventSelect(fd, NULL, 0); ioctlsocket(fd, FIONBIO, &opt); } @@ -83,6 +85,7 @@ void socket_set_nonblock(int fd) { unsigned long opt = 1; ioctlsocket(fd, FIONBIO, &opt); + qemu_fd_register(fd); } int inet_aton(const char *cp, struct in_addr *ia) diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h new file mode 100644 index 0000000000..3d3ac0fcef --- /dev/null +++ b/target-sparc/cpu-qom.h @@ -0,0 +1,75 @@ +/* + * QEMU SPARC CPU + * + * Copyright (c) 2012 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ +#ifndef QEMU_SPARC_CPU_QOM_H +#define QEMU_SPARC_CPU_QOM_H + +#include "qemu/cpu.h" +#include "cpu.h" + +#ifdef TARGET_SPARC64 +#define TYPE_SPARC_CPU "sparc64-cpu" +#else +#define TYPE_SPARC_CPU "sparc-cpu" +#endif + +#define SPARC_CPU_CLASS(klass) \ + OBJECT_CLASS_CHECK(SPARCCPUClass, (klass), TYPE_SPARC_CPU) +#define SPARC_CPU(obj) \ + OBJECT_CHECK(SPARCCPU, (obj), TYPE_SPARC_CPU) +#define SPARC_CPU_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SPARCCPUClass, (obj), TYPE_SPARC_CPU) + +/** + * SPARCCPUClass: + * @parent_reset: The parent class' reset handler. + * + * A SPARC CPU model. + */ +typedef struct SPARCCPUClass { + /*< private >*/ + CPUClass parent_class; + /*< public >*/ + + void (*parent_reset)(CPUState *cpu); +} SPARCCPUClass; + +/** + * SPARCCPU: + * @env: #CPUSPARCState + * + * A SPARC CPU. + */ +typedef struct SPARCCPU { + /*< private >*/ + CPUState parent_obj; + /*< public >*/ + + CPUSPARCState env; +} SPARCCPU; + +static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env) +{ + return SPARC_CPU(container_of(env, SPARCCPU, env)); +} + +#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e)) + + +#endif diff --git a/target-sparc/cpu_init.c b/target-sparc/cpu.c index 5c03f0b893..24f90f1ded 100644 --- a/target-sparc/cpu_init.c +++ b/target-sparc/cpu.c @@ -25,11 +25,23 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model); void cpu_state_reset(CPUSPARCState *env) { + cpu_reset(ENV_GET_CPU(env)); +} + +/* CPUClass::reset() */ +static void sparc_cpu_reset(CPUState *s) +{ + SPARCCPU *cpu = SPARC_CPU(s); + SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu); + CPUSPARCState *env = &cpu->env; + if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); log_cpu_state(env, 0); } + scc->parent_reset(s); + memset(env, 0, offsetof(CPUSPARCState, breakpoints)); tlb_flush(env, 1); env->cwp = 0; @@ -99,23 +111,18 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) return 0; } -static void cpu_sparc_close(CPUSPARCState *env) -{ - g_free(env->def); - g_free(env); -} - CPUSPARCState *cpu_sparc_init(const char *cpu_model) { + SPARCCPU *cpu; CPUSPARCState *env; - env = g_new0(CPUSPARCState, 1); - cpu_exec_init(env); + cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU)); + env = &cpu->env; gen_intermediate_code_init(env); if (cpu_sparc_register(env, cpu_model) < 0) { - cpu_sparc_close(env); + object_delete(OBJECT(cpu)); return NULL; } qemu_init_vcpu(env); @@ -847,3 +854,46 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf, env->fsr, env->y); #endif } + +static void sparc_cpu_initfn(Object *obj) +{ + SPARCCPU *cpu = SPARC_CPU(obj); + CPUSPARCState *env = &cpu->env; + + cpu_exec_init(env); +} + +static void sparc_cpu_uninitfn(Object *obj) +{ + SPARCCPU *cpu = SPARC_CPU(obj); + CPUSPARCState *env = &cpu->env; + + g_free(env->def); +} + +static void sparc_cpu_class_init(ObjectClass *oc, void *data) +{ + SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); + + scc->parent_reset = cc->reset; + cc->reset = sparc_cpu_reset; +} + +static const TypeInfo sparc_cpu_type_info = { + .name = TYPE_SPARC_CPU, + .parent = TYPE_CPU, + .instance_size = sizeof(SPARCCPU), + .instance_init = sparc_cpu_initfn, + .instance_finalize = sparc_cpu_uninitfn, + .abstract = false, + .class_size = sizeof(SPARCCPUClass), + .class_init = sparc_cpu_class_init, +}; + +static void sparc_cpu_register_types(void) +{ + type_register_static(&sparc_cpu_type_info); +} + +type_init(sparc_cpu_register_types) diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 885ad45c3a..865288cc94 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -691,6 +691,7 @@ static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp) #endif #include "cpu-all.h" +#include "cpu-qom.h" #ifdef TARGET_SPARC64 /* sun4u.c */ diff --git a/translate-all.c b/translate-all.c index 8c7d303d86..5bd2d3711a 100644 --- a/translate-all.c +++ b/translate-all.c @@ -109,11 +109,11 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr /* The cpu state corresponding to 'searched_pc' is restored. */ int cpu_restore_state(TranslationBlock *tb, - CPUArchState *env, unsigned long searched_pc) + CPUArchState *env, uintptr_t searched_pc) { TCGContext *s = &tcg_ctx; int j; - unsigned long tc_ptr; + uintptr_t tc_ptr; #ifdef CONFIG_PROFILER int64_t ti; #endif @@ -133,7 +133,7 @@ int cpu_restore_state(TranslationBlock *tb, } /* find opc index corresponding to search_pc */ - tc_ptr = (unsigned long)tb->tc_ptr; + tc_ptr = (uintptr_t)tb->tc_ptr; if (searched_pc < tc_ptr) return -1; |