F: tcg/ia64/
MIPS target
-M: Aurelien Jarno <aurelien@aurel32.ne>
+M: Aurelien Jarno <aurelien@aurel32.net>
S: Maintained
F: tcg/mips/
TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
$(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw)
-QEMU_CFLAGS+= -I.. -I../linux-headers -I$(TARGET_PATH) -DNEED_CPU_H
+ifdef CONFIG_LINUX
+QEMU_CFLAGS += -I../linux-headers
+endif
+QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H
include $(SRC_PATH)/Makefile.objs
# HELPER_CFLAGS is used for all the code compiled with static register
# variables
-%_helper.o cpu-exec.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+%_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
# Note: this is a workaround. The real fix is to avoid compiling
# cpu_signal_handler() in user-exec.c.
obj-i386-y += vmport.o
obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
obj-i386-y += debugcon.o multiboot.o
-obj-i386-y += pc_piix.o kvmclock.o
+obj-i386-y += pc_piix.o
+obj-i386-$(CONFIG_KVM) += kvmclock.o
obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
# shared objects
/* Some C libraries assume the heap immediately follows .bss, so
allocate it using sbrk. */
if (!ts->heap_limit) {
- long ret;
+ abi_ulong ret;
ts->heap_base = do_brk(0);
limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
/* Try a big heap, and reduce the size if that fails. */
for (;;) {
ret = do_brk(limit);
- if (ret != -1)
+ if (ret >= limit) {
break;
+ }
limit = (ts->heap_base >> 1) + (limit >> 1);
}
ts->heap_limit = limit;
break;
default:
- AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
+ AUD_log (AUDIO_CAP, "Reason: status code %" PRId32 "\n", (int32_t)status);
return;
}
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
- "Could not set device buffer frame size %ld\n",
- core->audioDevicePropertyBufferFrameSize);
+ "Could not set device buffer frame size %" PRIu32 "\n",
+ (uint32_t)core->audioDevicePropertyBufferFrameSize);
return -1;
}
bs_prev = bs;
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
if (total_sectors <= 0) {
- error_report("Error getting length of block device %s\n",
+ error_report("Error getting length of block device %s",
device_name);
return -EINVAL;
}
(1 << cluster_bits) != cluster_size)
{
error_report(
- "Cluster size must be a power of two between %d and %dk\n",
+ "Cluster size must be a power of two between %d and %dk",
1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
return -EINVAL;
}
static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)
{
if (acb->bh) {
- error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type);
+ error_report("bug: %d %d", acb->aiocb_type, acb->aiocb_type);
return -EIO;
}
acb->bh = qemu_bh_new(cb, acb);
- if (!acb->bh) {
- error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type);
- return -EIO;
- }
-
qemu_bh_schedule(acb->bh);
-
return 0;
}
ret = getaddrinfo(addr, port, &hints, &res0);
if (ret) {
- error_report("unable to get address info %s, %s\n",
+ error_report("unable to get address info %s, %s",
addr, strerror(errno));
return -1;
}
goto success;
}
fd = -1;
- error_report("failed connect to %s:%s\n", addr, port);
+ error_report("failed connect to %s:%s", addr, port);
success:
freeaddrinfo(res0);
return fd;
if (errno == EINTR || errno == EAGAIN) {
goto again;
}
- error_report("failed to recv a rsp, %s\n", strerror(errno));
+ error_report("failed to recv a rsp, %s", strerror(errno));
return 1;
}
ret = do_writev(sockfd, iov, sizeof(*hdr) + *wlen, 0);
if (ret) {
- error_report("failed to send a req, %s\n", strerror(errno));
+ error_report("failed to send a req, %s", strerror(errno));
ret = -1;
}
ret = do_read(sockfd, hdr, sizeof(*hdr));
if (ret) {
- error_report("failed to get a rsp, %s\n", strerror(errno));
+ error_report("failed to get a rsp, %s", strerror(errno));
ret = -1;
goto out;
}
if (*rlen) {
ret = do_read(sockfd, data, *rlen);
if (ret) {
- error_report("failed to get the data, %s\n", strerror(errno));
+ error_report("failed to get the data, %s", strerror(errno));
ret = -1;
goto out;
}
ret = add_aio_request(s, aio_req, acb->qiov->iov,
acb->qiov->niov, 0, acb->aiocb_type);
if (ret < 0) {
- error_report("add_aio_request is failed\n");
+ error_report("add_aio_request is failed");
free_aio_req(s, aio_req);
if (QLIST_EMPTY(&acb->aioreq_head)) {
sd_finish_aiocb(acb);
/* read a header */
ret = do_read(fd, &rsp, sizeof(rsp));
if (ret) {
- error_report("failed to get the header, %s\n", strerror(errno));
+ error_report("failed to get the header, %s", strerror(errno));
return;
}
}
}
if (!aio_req) {
- error_report("cannot find aio_req %x\n", rsp.id);
+ error_report("cannot find aio_req %x", rsp.id);
return;
}
ret = do_readv(fd, acb->qiov->iov, rsp.data_length,
aio_req->iov_offset);
if (ret) {
- error_report("failed to get the data, %s\n", strerror(errno));
+ error_report("failed to get the data, %s", strerror(errno));
return;
}
break;
if (rsp.result != SD_RES_SUCCESS) {
acb->ret = -EIO;
- error_report("%s\n", sd_strerror(rsp.result));
+ error_report("%s", sd_strerror(rsp.result));
}
rest = free_aio_req(s, aio_req);
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
- error_report("%s\n", strerror(errno));
+ error_report("%s", strerror(errno));
return -1;
}
ret = set_nodelay(fd);
if (ret) {
- error_report("%s\n", strerror(errno));
+ error_report("%s", strerror(errno));
closesocket(fd);
return -1;
}
}
if (rsp->result != SD_RES_SUCCESS) {
- error_report("cannot get vdi info, %s, %s %d %s\n",
+ error_report("cannot get vdi info, %s, %s %d %s",
sd_strerror(rsp->result), filename, snapid, tag);
ret = -1;
goto out;
uint64_t old_oid = aio_req->base_oid;
if (!nr_copies) {
- error_report("bug\n");
+ error_report("bug");
}
memset(&hdr, 0, sizeof(hdr));
/* send a header */
ret = do_write(s->fd, &hdr, sizeof(hdr));
if (ret) {
- error_report("failed to send a req, %s\n", strerror(errno));
+ error_report("failed to send a req, %s", strerror(errno));
return -EIO;
}
if (wlen) {
ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset);
if (ret) {
- error_report("failed to send a data, %s\n", strerror(errno));
+ error_report("failed to send a data, %s", strerror(errno));
return -EIO;
}
}
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
if (ret) {
- error_report("failed to send a request to the sheep\n");
+ error_report("failed to send a request to the sheep");
return -1;
}
case SD_RES_SUCCESS:
return 0;
default:
- error_report("%s\n", sd_strerror(rsp->result));
+ error_report("%s", sd_strerror(rsp->result));
return -1;
}
}
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
- error_report("failed to connect\n");
+ error_report("failed to connect");
goto out;
}
}
if (rsp->result != SD_RES_SUCCESS) {
- error_report("%s, %s\n", sd_strerror(rsp->result), filename);
+ error_report("%s, %s", sd_strerror(rsp->result), filename);
return -EIO;
}
memset(vdi, 0, sizeof(vdi));
memset(tag, 0, sizeof(tag));
if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) {
- error_report("invalid filename\n");
+ error_report("invalid filename");
return -EINVAL;
}
}
if (vdi_size > SD_MAX_VDI_SIZE) {
- error_report("too big image size\n");
+ error_report("too big image size");
return -EINVAL;
}
/* Currently, only Sheepdog backing image is supported. */
drv = bdrv_find_protocol(backing_file);
if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
- error_report("backing_file must be a sheepdog image\n");
+ error_report("backing_file must be a sheepdog image");
return -EINVAL;
}
s = bs->opaque;
if (!is_snapshot(&s->inode)) {
- error_report("cannot clone from a non snapshot vdi\n");
+ error_report("cannot clone from a non snapshot vdi");
bdrv_delete(bs);
return -EINVAL;
}
if (!ret && rsp->result != SD_RES_SUCCESS &&
rsp->result != SD_RES_VDI_NOT_LOCKED) {
- error_report("%s, %s\n", sd_strerror(rsp->result), s->name);
+ error_report("%s, %s", sd_strerror(rsp->result), s->name);
}
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL);
unsigned int datalen;
if (offset < s->inode.vdi_size) {
- error_report("shrinking is not supported\n");
+ error_report("shrinking is not supported");
return -EINVAL;
} else if (offset > SD_MAX_VDI_SIZE) {
- error_report("too big image size\n");
+ error_report("too big image size");
return -EINVAL;
}
close(fd);
if (ret < 0) {
- error_report("failed to update an inode.\n");
+ error_report("failed to update an inode.");
return -EIO;
}
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
- error_report("failed to connect\n");
+ error_report("failed to connect");
goto out;
}
ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
create, acb->aiocb_type);
if (ret < 0) {
- error_report("add_aio_request is failed\n");
+ error_report("add_aio_request is failed");
free_aio_req(s, aio_req);
acb->ret = -EIO;
goto out;
if (s->is_snapshot) {
error_report("You can't create a snapshot of a snapshot VDI, "
- "%s (%" PRIu32 ").\n", s->name, s->inode.vdi_id);
+ "%s (%" PRIu32 ").", s->name, s->inode.vdi_id);
return -EINVAL;
}
ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
s->inode.nr_copies, datalen, 0, 0);
if (ret < 0) {
- error_report("failed to write snapshot's inode.\n");
+ error_report("failed to write snapshot's inode.");
ret = -EIO;
goto cleanup;
}
ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1,
s->addr, s->port);
if (ret < 0) {
- error_report("failed to create inode for snapshot. %s\n",
+ error_report("failed to create inode for snapshot. %s",
strerror(errno));
ret = -EIO;
goto cleanup;
s->inode.nr_copies, datalen, 0);
if (ret < 0) {
- error_report("failed to read new inode info. %s\n", strerror(errno));
+ error_report("failed to read new inode info. %s", strerror(errno));
ret = -EIO;
goto cleanup;
}
ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1);
if (ret) {
- error_report("Failed to find_vdi_name\n");
+ error_report("Failed to find_vdi_name");
ret = -ENOENT;
goto out;
}
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
- error_report("failed to connect\n");
+ error_report("failed to connect");
goto out;
}
memcpy(&s->inode, buf, sizeof(s->inode));
if (!s->inode.vm_state_size) {
- error_report("Invalid snapshot\n");
+ error_report("Invalid snapshot");
ret = -ENOENT;
goto out;
}
qemu_free(buf);
qemu_free(old_s);
- error_report("failed to open. recover old bdrv_sd_state.\n");
+ error_report("failed to open. recover old bdrv_sd_state.");
return ret;
}
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
- error_report("failed to connect\n");
+ error_report("failed to connect");
goto out;
}
}
if (ret < 0) {
- error_report("failed to save vmstate %s\n", strerror(errno));
+ error_report("failed to save vmstate %s", strerror(errno));
ret = -EIO;
goto cleanup;
}
if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
if (!cyls) {
- error_report("'%s' trans must be used with cyls,heads and secs",
+ error_report("'%s' trans must be used with cyls, heads and secs",
buf);
return NULL;
}
#include "qemu.h"
#include "qemu-common.h"
/* For tb_lock */
-#include "exec-all.h"
+#include "cpu.h"
#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
curses=""
docs=""
fdt=""
-kvm="yes"
+kvm=""
nptl=""
sdl=""
vnc="yes"
xen_ctrl_version=""
linux_aio=""
attr=""
-vhost_net="yes"
+vhost_net=""
xfs=""
gprof="no"
linux="yes"
linux_user="yes"
usb="linux"
+ kvm="yes"
+ vhost_net="yes"
if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
audio_possible_drivers="$audio_possible_drivers fmod"
fi
pa)
audio_drv_probe $drv pulse/simple.h "-lpulse-simple -lpulse" \
- "pa_simple *s = NULL; pa_simple_free(s); return 0;"
+ "pa_simple *s = 0; pa_simple_free(s); return 0;"
libs_softmmu="-lpulse -lpulse-simple $libs_softmmu"
audio_pt_int="yes"
;;
fi
# use included Linux headers
-includes="-I\$(SRC_PATH)/linux-headers $includes"
-mkdir -p linux-headers
-case "$cpu" in
-i386|x86_64)
- symlink $source_path/linux-headers/asm-x86 linux-headers/asm
- ;;
-ppcemb|ppc|ppc64)
- symlink $source_path/linux-headers/asm-x86 linux-headers/asm
- ;;
-s390x)
- symlink $source_path/linux-headers/asm-s390 linux-headers/asm
- ;;
-esac
+if test "$linux" = "yes" ; then
+ includes="-I\$(SRC_PATH)/linux-headers $includes"
+ mkdir -p linux-headers
+ case "$cpu" in
+ i386|x86_64)
+ symlink $source_path/linux-headers/asm-x86 linux-headers/asm
+ ;;
+ ppcemb|ppc|ppc64)
+ symlink $source_path/linux-headers/asm-powerpc linux-headers/asm
+ ;;
+ s390x)
+ symlink $source_path/linux-headers/asm-s390 linux-headers/asm
+ ;;
+ esac
+fi
echo "LDFLAGS+=$ldflags" >> $config_target_mak
echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
done
mkdir -p $DIRS
for f in $FILES ; do
- test -e $f || symlink $source_path/$f $f
+ if [ -e "$source_path/$f" ] && ! [ -e "$f" ]; then
+ symlink "$source_path/$f" "$f"
+ fi
done
# temporary config to build submodules
static void dumb_display_init(void)
{
DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
+ int width = 640;
+ int height = 480;
+
ds->allocator = &default_allocator;
- ds->surface = qemu_create_displaysurface(ds, 640, 480);
+ if (is_fixedsize_console()) {
+ width = active_console->g_width;
+ height = active_console->g_height;
+ }
+ ds->surface = qemu_create_displaysurface(ds, width, height);
register_displaystate(ds);
}
void cpu_exit(CPUState *s);
-int qemu_cpu_has_work(CPUState *env);
+bool qemu_cpu_has_work(CPUState *env);
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ 0x01
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
-#include "exec.h"
+#include "cpu.h"
#include "disas.h"
#include "tcg.h"
#include "qemu-barrier.h"
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-// Work around ugly bugs in glibc that mangle global register contents
-#undef env
-#define env cpu_single_env
-#endif
-
int tb_invalidated_flag;
//#define CONFIG_DEBUG_EXEC
-int qemu_cpu_has_work(CPUState *env)
+bool qemu_cpu_has_work(CPUState *env)
{
return cpu_has_work(env);
}
-void cpu_loop_exit(void)
+void cpu_loop_exit(CPUState *env)
{
env->current_tb = NULL;
longjmp(env->jmp_env, 1);
restored in a state compatible with the CPU emulator
*/
#if defined(CONFIG_SOFTMMU)
-void cpu_resume_from_signal(CPUState *env1, void *puc)
+void cpu_resume_from_signal(CPUState *env, void *puc)
{
- env = env1;
-
/* XXX: restore cpu registers saved in host registers */
env->exception_index = -1;
/* Execute the code without caching the generated code. An interpreter
could be used if available. */
-static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
+static void cpu_exec_nocache(CPUState *env, int max_cycles,
+ TranslationBlock *orig_tb)
{
unsigned long next_tb;
TranslationBlock *tb;
max_cycles);
env->current_tb = tb;
/* execute the generated code */
- next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
+ next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
env->current_tb = NULL;
if ((next_tb & 3) == 2) {
tb_free(tb);
}
-static TranslationBlock *tb_find_slow(target_ulong pc,
+static TranslationBlock *tb_find_slow(CPUState *env,
+ target_ulong pc,
target_ulong cs_base,
uint64_t flags)
{
return tb;
}
-static inline TranslationBlock *tb_find_fast(void)
+static inline TranslationBlock *tb_find_fast(CPUState *env)
{
TranslationBlock *tb;
target_ulong cs_base, pc;
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags)) {
- tb = tb_find_slow(pc, cs_base, flags);
+ tb = tb_find_slow(env, pc, cs_base, flags);
}
return tb;
}
volatile sig_atomic_t exit_request;
-int cpu_exec(CPUState *env1)
+int cpu_exec(CPUState *env)
{
- volatile host_reg_t saved_env_reg;
int ret, interrupt_request;
TranslationBlock *tb;
uint8_t *tc_ptr;
unsigned long next_tb;
- if (env1->halted) {
- if (!cpu_has_work(env1)) {
+ if (env->halted) {
+ if (!cpu_has_work(env)) {
return EXCP_HALTED;
}
- env1->halted = 0;
+ env->halted = 0;
}
- cpu_single_env = env1;
-
- /* the access to env below is actually saving the global register's
- value, so that files not including target-xyz/exec.h are free to
- use it. */
- QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
- saved_env_reg = (host_reg_t) env;
- barrier();
- env = env1;
+ cpu_single_env = env;
if (unlikely(exit_request)) {
env->exit_request = 1;
/* prepare setjmp context for exception handling */
for(;;) {
if (setjmp(env->jmp_env) == 0) {
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
/* if an exception is pending, we execute it here */
if (env->exception_index >= 0) {
if (env->exception_index >= EXCP_INTERRUPT) {
which will be handled outside the cpu execution
loop */
#if defined(TARGET_I386)
- do_interrupt_user(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip);
- /* successfully delivered */
- env->old_exception = -1;
+ do_interrupt(env);
#endif
ret = env->exception_index;
break;
#else
-#if defined(TARGET_I386)
- /* simulate a real cpu exception. On i386, it can
- trigger new exceptions, but we do not handle
- double or triple faults yet. */
- do_interrupt(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
- /* successfully delivered */
- env->old_exception = -1;
-#elif defined(TARGET_PPC)
- do_interrupt(env);
-#elif defined(TARGET_LM32)
- do_interrupt(env);
-#elif defined(TARGET_MICROBLAZE)
- do_interrupt(env);
-#elif defined(TARGET_MIPS)
- do_interrupt(env);
-#elif defined(TARGET_SPARC)
do_interrupt(env);
-#elif defined(TARGET_ARM)
- do_interrupt(env);
-#elif defined(TARGET_UNICORE32)
- do_interrupt(env);
-#elif defined(TARGET_SH4)
- do_interrupt(env);
-#elif defined(TARGET_ALPHA)
- do_interrupt(env);
-#elif defined(TARGET_CRIS)
- do_interrupt(env);
-#elif defined(TARGET_M68K)
- do_interrupt(0);
-#elif defined(TARGET_S390X)
- do_interrupt(env);
-#endif
env->exception_index = -1;
#endif
}
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
env->interrupt_request &= ~CPU_INTERRUPT_HALT;
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#endif
#if defined(TARGET_I386)
if (interrupt_request & CPU_INTERRUPT_INIT) {
- svm_check_intercept(SVM_EXIT_INIT);
+ svm_check_intercept(env, SVM_EXIT_INIT);
do_cpu_init(env);
env->exception_index = EXCP_HALTED;
- cpu_loop_exit();
+ cpu_loop_exit(env);
} else if (interrupt_request & CPU_INTERRUPT_SIPI) {
do_cpu_sipi(env);
} else if (env->hflags2 & HF2_GIF_MASK) {
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
!(env->hflags & HF_SMM_MASK)) {
- svm_check_intercept(SVM_EXIT_SMI);
+ svm_check_intercept(env, SVM_EXIT_SMI);
env->interrupt_request &= ~CPU_INTERRUPT_SMI;
- do_smm_enter();
+ do_smm_enter(env);
next_tb = 0;
} else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
!(env->hflags2 & HF2_NMI_MASK)) {
env->interrupt_request &= ~CPU_INTERRUPT_NMI;
env->hflags2 |= HF2_NMI_MASK;
- do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
next_tb = 0;
} else if (interrupt_request & CPU_INTERRUPT_MCE) {
env->interrupt_request &= ~CPU_INTERRUPT_MCE;
- do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
+ do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
next_tb = 0;
} else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
(((env->hflags2 & HF2_VINTR_MASK) &&
(env->eflags & IF_MASK &&
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
int intno;
- svm_check_intercept(SVM_EXIT_INTR);
+ svm_check_intercept(env, SVM_EXIT_INTR);
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
- do_interrupt(intno, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, intno, 1);
/* ensure that no TB jump will be modified as
the program flow was changed */
next_tb = 0;
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
int intno;
/* FIXME: this should respect TPR */
- svm_check_intercept(SVM_EXIT_VINTR);
+ svm_check_intercept(env, SVM_EXIT_VINTR);
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
- do_interrupt(intno, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, intno, 1);
env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
next_tb = 0;
#endif
provide/save the vector when the interrupt is
first signalled. */
env->exception_index = env->pending_vector;
- do_interrupt(1);
+ do_interrupt_m68k_hardirq(env);
next_tb = 0;
}
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
if (unlikely(env->exit_request)) {
env->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
/* restore flags in standard format */
#if defined(TARGET_I386)
- env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
+ | (DF & DF_MASK);
log_cpu_state(env, X86_DUMP_CCOP);
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
#elif defined(TARGET_M68K)
}
#endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */
spin_lock(&tb_lock);
- tb = tb_find_fast();
+ tb = tb_find_fast(env);
/* Note: we do it here to avoid a gcc bug on Mac OS X when
doing it in tb_find_slow */
if (tb_invalidated_flag) {
if (likely(!env->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
- next_tb = tcg_qemu_tb_exec(tc_ptr);
+ next_tb = tcg_qemu_tb_exec(env, tc_ptr);
if ((next_tb & 3) == 2) {
/* Instruction counter expired. */
int insns_left;
} else {
if (insns_left > 0) {
/* Execute remaining instructions. */
- cpu_exec_nocache(insns_left, tb);
+ cpu_exec_nocache(env, insns_left, tb);
}
env->exception_index = EXCP_INTERRUPT;
next_tb = 0;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
}
}
#if defined(TARGET_I386)
/* restore flags in standard format */
- env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
+ | (DF & DF_MASK);
#elif defined(TARGET_ARM)
/* XXX: Save/restore host fpu exception state?. */
#elif defined(TARGET_UNICORE32)
#error unsupported target CPU
#endif
- /* restore global registers */
- barrier();
- env = (void *) saved_env_reg;
-
/* fail safe : never use cpu_single_env outside cpu_exec() */
cpu_single_env = NULL;
return ret;
#include "gdbstub.h"
#include "dma.h"
#include "kvm.h"
-#include "exec-all.h"
#include "qemu-thread.h"
#include "cpus.h"
+
+#ifndef _WIN32
#include "compatfd.h"
+#endif
#ifdef SIGRTMIN
#define SIG_IPI (SIGRTMIN+4)
#include <errno.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
/* Filled in by elfload.c. Simplistic, but will do for now. */
#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
#define DISAS_TB_JUMP 3 /* only pc was modified statically */
+struct TranslationBlock;
typedef struct TranslationBlock TranslationBlock;
/* XXX: make safe guess about sizes */
target_ulong pc, target_ulong cs_base, int flags,
int cflags);
void cpu_exec_init(CPUState *env);
-void QEMU_NORETURN cpu_loop_exit(void);
+void QEMU_NORETURN cpu_loop_exit(CPUState *env1);
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int is_cpu_write_access);
#include "qemu-common.h"
#include "cpu.h"
-#include "exec-all.h"
#include "tcg.h"
#include "hw/hw.h"
#include "hw/qdev.h"
unsigned int n, tb_page_addr_t page_addr)
{
PageDesc *p;
- TranslationBlock *last_first_tb;
+#ifndef CONFIG_USER_ONLY
+ bool page_already_protected;
+#endif
tb->page_addr[n] = page_addr;
p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1);
tb->page_next[n] = p->first_tb;
- last_first_tb = p->first_tb;
+#ifndef CONFIG_USER_ONLY
+ page_already_protected = p->first_tb != NULL;
+#endif
p->first_tb = (TranslationBlock *)((long)tb | n);
invalidate_page_bitmap(p);
/* if some code is already present, then the pages are already
protected. So we handle the case where only the first TB is
allocated in a physical page */
- if (!last_first_tb) {
+ if (!page_already_protected) {
tlb_protect_code(page_addr);
}
#endif
#define MAX_PACKET_LENGTH 4096
-#include "exec-all.h"
+#include "cpu.h"
#include "qemu_socket.h"
#include "kvm.h"
* Copyright (c) 2006-2007 CodeSourcery.
* Written by Paul Brook
*
- * This code is licenced under the GPL.
+ * This code is licensed under the GPL.
*/
#include "sysbus.h"
/* Bitbanded IO. Each word corresponds to a single bit. */
-/* Get the byte address of the real memory for a bitband acess. */
+/* Get the byte address of the real memory for a bitband access. */
static inline uint32_t bitband_addr(void * opaque, uint32_t addr)
{
uint32_t res;
*
*/
+#ifdef CONFIG_KVM
+
void kvmclock_create(void);
+
+#else /* CONFIG_KVM */
+
+static inline void kvmclock_create(void)
+{
+}
+
+#endif /* !CONFIG_KVM */
break;
default:
- error_report("lm32_sys: write access to unkown register 0x"
+ error_report("lm32_sys: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
r = (uint32_t)ptimer_get_count(s->ptimer);
break;
default:
- error_report("lm32_timer: read access to unkown register 0x"
+ error_report("lm32_timer: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
TARGET_FMT_plx, addr << 2);
break;
default:
- error_report("lm32_timer: write access to unkown register 0x"
+ error_report("lm32_timer: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
TARGET_FMT_plx, addr << 2);
break;
default:
- error_report("lm32_uart: read access to unkown register 0x"
+ error_report("lm32_uart: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
TARGET_FMT_plx, addr << 2);
break;
default:
- error_report("lm32_uart: write access to unkown register 0x"
+ error_report("lm32_uart: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
break;
default:
- error_report("milkymist_ac97: read access to unkown register 0x"
+ error_report("milkymist_ac97: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
break;
default:
- error_report("milkymist_ac97: write access to unkown register 0x"
+ error_report("milkymist_ac97: write access to unknown register 0x"
TARGET_FMT_plx, addr);
break;
}
break;
default:
- error_report("milkymist_memcard: read access to unkown register 0x"
+ error_report("milkymist_memcard: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
break;
default:
- error_report("milkymist_memcard: write access to unkown register 0x"
+ error_report("milkymist_memcard: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
uint8_t *buf = s->tx_buf;
if (txcount < 64) {
- error_report("milkymist_minimac2: ethernet frame too small (%u < %u)\n",
+ error_report("milkymist_minimac2: ethernet frame too small (%u < %u)",
txcount, 64);
goto err;
}
if (txcount > MINIMAC2_MTU) {
- error_report("milkymist_minimac2: MTU exceeded (%u > %u)\n",
+ error_report("milkymist_minimac2: MTU exceeded (%u > %u)",
txcount, MINIMAC2_MTU);
goto err;
}
if (memcmp(buf, preamble_sfd, 8) != 0) {
error_report("milkymist_minimac2: frame doesn't contain the preamble "
- "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)\n",
+ "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
goto err;
}
} break;
default:
- error_report("milkymist_pfpu: unknown opcode %d\n", op);
+ error_report("milkymist_pfpu: unknown opcode %d", op);
break;
}
/* decode at most MICROCODE_WORDS instructions */
if (i++ >= MICROCODE_WORDS) {
error_report("milkymist_pfpu: too many instructions "
- "executed in microcode. No VECTOUT?\n");
+ "executed in microcode. No VECTOUT?");
break;
}
}
{
if (offset + len >= s->dmem_size) {
error_report("milkymist_softusb: read dmem out of bounds "
- "at offset 0x%x, len %d\n", offset, len);
+ "at offset 0x%x, len %d", offset, len);
return;
}
{
if (offset + len >= s->dmem_size) {
error_report("milkymist_softusb: write dmem out of bounds "
- "at offset 0x%x, len %d\n", offset, len);
+ "at offset 0x%x, len %d", offset, len);
return;
}
{
if (offset + len >= s->pmem_size) {
error_report("milkymist_softusb: read pmem out of bounds "
- "at offset 0x%x, len %d\n", offset, len);
+ "at offset 0x%x, len %d", offset, len);
return;
}
{
if (offset + len >= s->pmem_size) {
error_report("milkymist_softusb: write pmem out of bounds "
- "at offset 0x%x, len %d\n", offset, len);
+ "at offset 0x%x, len %d", offset, len);
return;
}
break;
default:
- error_report("milkymist_sysctl: read access to unkown register 0x"
+ error_report("milkymist_sysctl: read access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
break;
default:
- error_report("milkymist_sysctl: write access to unkown register 0x"
+ error_report("milkymist_sysctl: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
static void tmu2_check_registers(MilkymistTMU2State *s)
{
if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) {
- error_report("milkymist_tmu2: max brightness is %d\n", MAX_BRIGHTNESS);
+ error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS);
}
if (s->regs[R_ALPHA] > MAX_ALPHA) {
- error_report("milkymist_tmu2: max alpha is %d\n", MAX_ALPHA);
+ error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA);
}
if (s->regs[R_VERTICESADDR] & 0x07) {
error_report("milkymist_tmu2: vertex mesh address has to be 64-bit "
- "aligned\n");
+ "aligned");
}
if (s->regs[R_TEXFBUF] & 0x01) {
error_report("milkymist_tmu2: texture buffer address has to be "
- "16-bit aligned\n");
+ "16-bit aligned");
}
}
DeviceInfo *info = dev->info;
if (qdev_init(dev) < 0) {
- error_report("Initialization of device %s failed\n", info->name);
+ error_report("Initialization of device %s failed", info->name);
exit(1);
}
}
#include "sh7750_regs.h"
#include "sh7750_regnames.h"
#include "sh_intc.h"
-#include "exec-all.h"
#include "cpu.h"
#define NB_DEVICES 4
#include "qemu-char.h"
#include "sysemu.h"
#include "qemu-char.h"
-#include "exec-all.h"
#include "exec.h"
#include "helper_regs.h"
#include "hw/spapr.h"
}
if (strncmp(rev, "sa1110", 6)) {
- error_report("Machine requires a SA1110 processor.\n");
+ error_report("Machine requires a SA1110 processor.");
exit(1);
}
s->env = cpu_init(rev);
if (!s->env) {
- error_report("Unable to find CPU definition\n");
+ error_report("Unable to find CPU definition");
exit(1);
}
return -1;
}
if (s->card != NULL) {
- error_report("Warning: usb-ccid card already full, not adding\n");
+ error_report("Warning: usb-ccid card already full, not adding");
return -1;
}
ret = info->initfn ? info->initfn(card) : ret;
cpkt.event = lduw_p(&gcpkt->event);
cpkt.value = lduw_p(&gcpkt->value);
- port = find_port_by_id(vser, ldl_p(&gcpkt->id));
- if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)
- return;
-
- info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
-
- switch(cpkt.event) {
- case VIRTIO_CONSOLE_DEVICE_READY:
+ if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
if (!cpkt.value) {
- error_report("virtio-serial-bus: Guest failure in adding device %s\n",
+ error_report("virtio-serial-bus: Guest failure in adding device %s",
vser->bus.qbus.name);
- break;
+ return;
}
/*
* The device is up, we can now tell the device about all the
QTAILQ_FOREACH(port, &vser->ports, next) {
send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
}
- break;
+ return;
+ }
+ port = find_port_by_id(vser, ldl_p(&gcpkt->id));
+ if (!port) {
+ error_report("virtio-serial-bus: Unexpected port id %u for device %s\n",
+ ldl_p(&gcpkt->id), vser->bus.qbus.name);
+ return;
+ }
+
+ info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
+
+ switch(cpkt.event) {
case VIRTIO_CONSOLE_PORT_READY:
if (!cpkt.value) {
- error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",
+ error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
port->id, vser->bus.qbus.name);
break;
}
plugging_port0 = info->is_console && !find_port_by_id(port->vser, 0);
if (find_port_by_id(port->vser, port->id)) {
- error_report("virtio-serial-bus: A port already exists at id %u\n",
+ error_report("virtio-serial-bus: A port already exists at id %u",
port->id);
return -1;
}
} else {
port->id = find_free_port_id(port->vser);
if (port->id == VIRTIO_CONSOLE_BAD_ID) {
- error_report("virtio-serial-bus: Maximum port limit for this device reached\n");
+ error_report("virtio-serial-bus: Maximum port limit for this device reached");
return -1;
}
}
max_nr_ports = tswap32(port->vser->config.max_nr_ports);
if (port->id >= max_nr_ports) {
- error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
+ error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
max_nr_ports - 1);
return -1;
}
/* Check it isn't doing very strange things with descriptor numbers. */
if (nheads > vdev->vq[i].vring.num) {
error_report("VQ %d size 0x%x Guest index 0x%x "
- "inconsistent with Host index 0x%x: delta 0x%x\n",
+ "inconsistent with Host index 0x%x: delta 0x%x",
i, vdev->vq[i].vring.num,
vring_avail_idx(&vdev->vq[i]),
vdev->vq[i].last_avail_idx, nheads);
}
} else if (vdev->vq[i].last_avail_idx) {
error_report("VQ %d address 0x0 "
- "inconsistent with Host index 0x%x\n",
+ "inconsistent with Host index 0x%x",
i, vdev->vq[i].last_avail_idx);
return -1;
}
#include "qemu-common.h"
#include "hw/hw.h"
-#include "exec-all.h"
+#include "cpu.h"
#include "gdbstub.h"
#include "kvm.h"
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
-#define DLINFO_ITEMS 12
+#define DLINFO_ITEMS 13
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
{
{
abi_ulong sp;
int size;
+ int i;
+ abi_ulong u_rand_bytes;
+ uint8_t k_rand_bytes[16];
abi_ulong u_platform;
const char *k_platform;
const int n = sizeof(elf_addr_t);
/* FIXME - check return value of memcpy_to_target() for failure */
memcpy_to_target(sp, k_platform, len);
}
+
+ /*
+ * Generate 16 random bytes for userspace PRNG seeding (not
+ * cryptically secure but it's not the aim of QEMU).
+ */
+ srand((unsigned int) time(NULL));
+ for (i = 0; i < 16; i++) {
+ k_rand_bytes[i] = rand();
+ }
+ sp -= 16;
+ u_rand_bytes = sp;
+ /* FIXME - check return value of memcpy_to_target() for failure */
+ memcpy_to_target(sp, k_rand_bytes, 16);
+
/*
* Force 16 byte _final_ alignment here for generality.
*/
NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
+ NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
+
if (k_platform)
NEW_AUX_ENT(AT_PLATFORM, u_platform);
#ifdef ARCH_DLINFO
return sp;
}
+static void probe_guest_base(const char *image_name,
+ abi_ulong loaddr, abi_ulong hiaddr)
+{
+ /* Probe for a suitable guest base address, if the user has not set
+ * it explicitly, and set guest_base appropriately.
+ * In case of error we will print a suitable message and exit.
+ */
+#if defined(CONFIG_USE_GUEST_BASE)
+ const char *errmsg;
+ if (!have_guest_base && !reserved_va) {
+ unsigned long host_start, real_start, host_size;
+
+ /* Round addresses to page boundaries. */
+ loaddr &= qemu_host_page_mask;
+ hiaddr = HOST_PAGE_ALIGN(hiaddr);
+
+ if (loaddr < mmap_min_addr) {
+ host_start = HOST_PAGE_ALIGN(mmap_min_addr);
+ } else {
+ host_start = loaddr;
+ if (host_start != loaddr) {
+ errmsg = "Address overflow loading ELF binary";
+ goto exit_errmsg;
+ }
+ }
+ host_size = hiaddr - loaddr;
+ while (1) {
+ /* Do not use mmap_find_vma here because that is limited to the
+ guest address space. We are going to make the
+ guest address space fit whatever we're given. */
+ real_start = (unsigned long)
+ mmap((void *)host_start, host_size, PROT_NONE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
+ if (real_start == (unsigned long)-1) {
+ goto exit_perror;
+ }
+ if (real_start == host_start) {
+ break;
+ }
+ /* That address didn't work. Unmap and try a different one.
+ The address the host picked because is typically right at
+ the top of the host address space and leaves the guest with
+ no usable address space. Resort to a linear search. We
+ already compensated for mmap_min_addr, so this should not
+ happen often. Probably means we got unlucky and host
+ address space randomization put a shared library somewhere
+ inconvenient. */
+ munmap((void *)real_start, host_size);
+ host_start += qemu_host_page_size;
+ if (host_start == loaddr) {
+ /* Theoretically possible if host doesn't have any suitably
+ aligned areas. Normally the first mmap will fail. */
+ errmsg = "Unable to find space for application";
+ goto exit_errmsg;
+ }
+ }
+ qemu_log("Relocating guest address space from 0x"
+ TARGET_ABI_FMT_lx " to 0x%lx\n",
+ loaddr, real_start);
+ guest_base = real_start - loaddr;
+ }
+ return;
+
+exit_perror:
+ errmsg = strerror(errno);
+exit_errmsg:
+ fprintf(stderr, "%s: %s\n", image_name, errmsg);
+ exit(-1);
+#endif
+}
+
+
/* Load an ELF image into the address space.
IMAGE_NAME is the filename of the image, to use in error messages.
/* This is the main executable. Make sure that the low
address does not conflict with MMAP_MIN_ADDR or the
QEMU application itself. */
-#if defined(CONFIG_USE_GUEST_BASE)
- /*
- * In case where user has not explicitly set the guest_base, we
- * probe here that should we set it automatically.
- */
- if (!have_guest_base && !reserved_va) {
- unsigned long host_start, real_start, host_size;
-
- /* Round addresses to page boundaries. */
- loaddr &= qemu_host_page_mask;
- hiaddr = HOST_PAGE_ALIGN(hiaddr);
-
- if (loaddr < mmap_min_addr) {
- host_start = HOST_PAGE_ALIGN(mmap_min_addr);
- } else {
- host_start = loaddr;
- if (host_start != loaddr) {
- errmsg = "Address overflow loading ELF binary";
- goto exit_errmsg;
- }
- }
- host_size = hiaddr - loaddr;
- while (1) {
- /* Do not use mmap_find_vma here because that is limited to the
- guest address space. We are going to make the
- guest address space fit whatever we're given. */
- real_start = (unsigned long)
- mmap((void *)host_start, host_size, PROT_NONE,
- MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
- if (real_start == (unsigned long)-1) {
- goto exit_perror;
- }
- if (real_start == host_start) {
- break;
- }
- /* That address didn't work. Unmap and try a different one.
- The address the host picked because is typically right at
- the top of the host address space and leaves the guest with
- no usable address space. Resort to a linear search. We
- already compensated for mmap_min_addr, so this should not
- happen often. Probably means we got unlucky and host
- address space randomization put a shared library somewhere
- inconvenient. */
- munmap((void *)real_start, host_size);
- host_start += qemu_host_page_size;
- if (host_start == loaddr) {
- /* Theoretically possible if host doesn't have any suitably
- aligned areas. Normally the first mmap will fail. */
- errmsg = "Unable to find space for application";
- goto exit_errmsg;
- }
- }
- qemu_log("Relocating guest address space from 0x"
- TARGET_ABI_FMT_lx " to 0x%lx\n", loaddr, real_start);
- guest_base = real_start - loaddr;
- }
-#endif
+ probe_guest_base(image_name, loaddr, hiaddr);
}
load_bias = load_addr - loaddr;
{
int i, shnum, nsyms, sym_idx = 0, str_idx = 0;
struct elf_shdr *shdr;
- char *strings;
- struct syminfo *s;
- struct elf_sym *syms, *new_syms;
+ char *strings = NULL;
+ struct syminfo *s = NULL;
+ struct elf_sym *new_syms, *syms = NULL;
shnum = hdr->e_shnum;
i = shnum * sizeof(struct elf_shdr);
/* Now know where the strtab and symtab are. Snarf them. */
s = malloc(sizeof(*s));
if (!s) {
- return;
+ goto give_up;
}
i = shdr[str_idx].sh_size;
s->disas_strtab = strings = malloc(i);
if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {
- free(s);
- free(strings);
- return;
+ goto give_up;
}
i = shdr[sym_idx].sh_size;
syms = malloc(i);
if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {
- free(s);
- free(strings);
- free(syms);
- return;
+ goto give_up;
}
nsyms = i / sizeof(struct elf_sym);
}
}
+ /* No "useful" symbol. */
+ if (nsyms == 0) {
+ goto give_up;
+ }
+
/* Attempt to free the storage associated with the local symbols
that we threw away. Whether or not this has any effect on the
memory allocation depends on the malloc implementation and how
many symbols we managed to discard. */
new_syms = realloc(syms, nsyms * sizeof(*syms));
if (new_syms == NULL) {
- free(s);
- free(syms);
- free(strings);
- return;
+ goto give_up;
}
syms = new_syms;
s->lookup_symbol = lookup_symbolxx;
s->next = syminfos;
syminfos = s;
+
+ return;
+
+give_up:
+ free(s);
+ free(strings);
+ free(syms);
}
int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
abi_long result;
abi_ulong realdatastart = 0;
abi_ulong text_len, data_len, bss_len, stack_len, flags;
- abi_ulong memp = 0; /* for finding the brk area */
abi_ulong extra;
abi_ulong reloc = 0, rp;
int i, rev, relocs = 0;
abi_ulong fpos;
- abi_ulong start_code, end_code;
+ abi_ulong start_code;
abi_ulong indx_len;
hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */
}
reloc = datapos + (ntohl(hdr->reloc_start) - text_len);
- memp = realdatastart;
} else {
realdatastart = textpos + ntohl(hdr->data_start);
datapos = realdatastart + indx_len;
reloc = (textpos + ntohl(hdr->reloc_start) + indx_len);
- memp = textpos;
#ifdef CONFIG_BINFMT_ZFLAT
#error code needs checking
/* The main program needs a little extra setup in the task structure */
start_code = textpos + sizeof (struct flat_hdr);
- end_code = textpos + text_len;
DBG_FLT("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n",
id ? "Lib" : "Load", bprm->filename,
- (int) start_code, (int) end_code,
+ (int) start_code, (int) (textpos + text_len),
(int) datapos,
(int) (datapos + data_len),
(int) (datapos + data_len),
return 0;
}
-static int in_group_p(gid_t g)
-{
- /* return TRUE if we're in the specified group, FALSE otherwise */
- int ngroup;
- int i;
- gid_t grouplist[NGROUPS];
-
- ngroup = getgroups(NGROUPS, grouplist);
- for(i = 0; i < ngroup; i++) {
- if(grouplist[i] == g) {
- return 1;
- }
- }
- return 0;
-}
-
static int count(char ** vec)
{
int i;
{
struct stat st;
int mode;
- int retval, id_change;
+ int retval;
if(fstat(bprm->fd, &st) < 0) {
return(-errno);
bprm->e_uid = geteuid();
bprm->e_gid = getegid();
- id_change = 0;
/* Set-uid? */
if(mode & S_ISUID) {
bprm->e_uid = st.st_uid;
- if(bprm->e_uid != geteuid()) {
- id_change = 1;
- }
}
/* Set-gid? */
*/
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
bprm->e_gid = st.st_gid;
- if (!in_group_p(bprm->e_gid)) {
- id_change = 1;
- }
}
retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE);
#include "qemu.h"
#include "qemu-common.h"
#include "cache-utils.h"
-/* For tb_lock */
-#include "exec-all.h"
+#include "cpu.h"
#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
env->regs[R_EDX],
env->regs[R_ESI],
env->regs[R_EDI],
- env->regs[R_EBP]);
+ env->regs[R_EBP],
+ 0, 0);
break;
#ifndef TARGET_ABI32
case EXCP_SYSCALL:
env->regs[R_EDX],
env->regs[10],
env->regs[8],
- env->regs[9]);
+ env->regs[9],
+ 0, 0);
env->eip = env->exception_next_eip;
break;
#endif
env->regs[2],
env->regs[3],
env->regs[4],
- env->regs[5]);
+ env->regs[5],
+ 0, 0);
}
} else {
goto error;
env->regs[2],
env->regs[3],
env->regs[4],
- env->regs[5]);
+ env->regs[5],
+ 0, 0);
}
} else {
goto error;
ret = do_syscall (env, env->gregs[1],
env->regwptr[0], env->regwptr[1],
env->regwptr[2], env->regwptr[3],
- env->regwptr[4], env->regwptr[5]);
+ env->regwptr[4], env->regwptr[5],
+ 0, 0);
if ((abi_ulong)ret >= (abi_ulong)(-515)) {
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
env->xcc |= PSR_CARRY;
env->crf[0] &= ~0x1;
ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
env->gpr[5], env->gpr[6], env->gpr[7],
- env->gpr[8]);
+ env->gpr[8], 0, 0);
if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) {
/* Returning from a successful sigreturn syscall.
Avoid corrupting register state. */
env->active_tc.gpr[5],
env->active_tc.gpr[6],
env->active_tc.gpr[7],
- arg5, arg6/*, arg7, arg8*/);
+ arg5, arg6, arg7, arg8);
}
if (ret == -TARGET_QEMU_ESIGRETURN) {
/* Returning from a successful sigreturn syscall.
env->gregs[6],
env->gregs[7],
env->gregs[0],
- env->gregs[1]);
+ env->gregs[1],
+ 0, 0);
env->gregs[0] = ret;
break;
case EXCP_INTERRUPT:
env->regs[12],
env->regs[13],
env->pregs[7],
- env->pregs[11]);
+ env->pregs[11],
+ 0, 0);
env->regs[10] = ret;
break;
case EXCP_DEBUG:
env->regs[7],
env->regs[8],
env->regs[9],
- env->regs[10]);
+ env->regs[10],
+ 0, 0);
env->regs[3] = ret;
env->sregs[SR_PC] = env->regs[14];
break;
env->dregs[3],
env->dregs[4],
env->dregs[5],
- env->aregs[0]);
+ env->aregs[0],
+ 0, 0);
}
break;
case EXCP_INTERRUPT:
sysret = do_syscall(env, trapnr,
env->ir[IR_A0], env->ir[IR_A1],
env->ir[IR_A2], env->ir[IR_A3],
- env->ir[IR_A4], env->ir[IR_A5]);
+ env->ir[IR_A4], env->ir[IR_A5],
+ 0, 0);
if (trapnr == TARGET_NR_sigreturn
|| trapnr == TARGET_NR_rt_sigreturn) {
break;
env->regs[4],
env->regs[5],
env->regs[6],
- env->regs[7]);
+ env->regs[7],
+ 0, 0);
}
break;
case EXCP_ADDR:
void syscall_init(void);
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
- abi_long arg5, abi_long arg6);
+ abi_long arg5, abi_long arg6, abi_long arg7,
+ abi_long arg8);
void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
extern THREAD CPUState *thread_env;
void cpu_loop(CPUState *env);
env->regs[R_ECX] = tswapl(sc->ecx);
env->eip = tswapl(sc->eip);
- cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
- cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
+ cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
+ cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
tmpflags = tswapl(sc->eflags);
env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
uint32_t up_psr, pc, npc;
target_sigset_t set;
sigset_t host_set;
- abi_ulong fpu_save_addr;
int err, i;
sf_addr = env->regwptr[UREG_FP];
err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
}
- err |= __get_user(fpu_save_addr, &sf->fpu_save);
-
- //if (fpu_save)
- // err |= restore_fpu_state(env, fpu_save);
+ /* FIXME: implement FPU save/restore:
+ * __get_user(fpu_save, &sf->fpu_save);
+ * if (fpu_save)
+ * err |= restore_fpu_state(env, fpu_save);
+ */
/* This is pretty much atomic, no amount locking would prevent
* the races which exist anyways.
target_mc_gregset_t *grp;
abi_ulong pc, npc, tstate;
abi_ulong fp, i7, w_addr;
- unsigned char fenab;
int err;
unsigned int i;
if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
abi_ulong) != 0)
goto do_sigsegv;
- err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
+ /* FIXME this does not match how the kernel handles the FPU in
+ * its sparc64_set_context implementation. In particular the FPU
+ * is only restored if fenab is non-zero in:
+ * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
+ */
err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
{
uint32_t *src, *dst;
size_t, sigsetsize)
#endif
+#if defined(TARGET_NR_pselect6)
+#ifndef __NR_pselect6
+# define __NR_pselect6 -1
+#endif
+#define __NR_sys_pselect6 __NR_pselect6
+_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
+ fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
+#endif
+
extern int personality(int);
extern int flock(int, int);
extern int setfsuid(int);
static abi_ulong target_brk;
static abi_ulong target_original_brk;
+static abi_ulong brk_page;
void target_set_brk(abi_ulong new_brk)
{
target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
+ brk_page = HOST_PAGE_ALIGN(target_brk);
}
+//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
+#define DEBUGF_BRK(message, args...)
+
/* do_brk() must return target values and target errnos. */
abi_long do_brk(abi_ulong new_brk)
{
- abi_ulong brk_page;
abi_long mapped_addr;
int new_alloc_size;
- if (!new_brk)
+ DEBUGF_BRK("do_brk(%#010x) -> ", new_brk);
+
+ if (!new_brk) {
+ DEBUGF_BRK("%#010x (!new_brk)\n", target_brk);
return target_brk;
- if (new_brk < target_original_brk)
+ }
+ if (new_brk < target_original_brk) {
+ DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk);
return target_brk;
+ }
- brk_page = HOST_PAGE_ALIGN(target_brk);
-
- /* If the new brk is less than this, set it and we're done... */
- if (new_brk < brk_page) {
+ /* If the new brk is less than the highest page reserved to the
+ * target heap allocation, set it and we're almost done... */
+ if (new_brk <= brk_page) {
+ /* Heap contents are initialized to zero, as for anonymous
+ * mapped pages. */
+ if (new_brk > target_brk) {
+ memset(g2h(target_brk), 0, new_brk - target_brk);
+ }
target_brk = new_brk;
+ DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk);
return target_brk;
}
- /* We need to allocate more memory after the brk... */
- new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
+ /* We need to allocate more memory after the brk... Note that
+ * we don't use MAP_FIXED because that will map over the top of
+ * any existing mapping (like the one with the host libc or qemu
+ * itself); instead we treat "mapped but at wrong address" as
+ * a failure and unmap again.
+ */
+ new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
+ MAP_ANON|MAP_PRIVATE, 0, 0));
+
+ if (mapped_addr == brk_page) {
+ target_brk = new_brk;
+ brk_page = HOST_PAGE_ALIGN(target_brk);
+ DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk);
+ return target_brk;
+ } else if (mapped_addr != -1) {
+ /* Mapped but at wrong address, meaning there wasn't actually
+ * enough space for this brk.
+ */
+ target_munmap(mapped_addr, new_alloc_size);
+ mapped_addr = -1;
+ DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk);
+ }
+ else {
+ DEBUGF_BRK("%#010x (otherwise)\n", target_brk);
+ }
#if defined(TARGET_ALPHA)
/* We (partially) emulate OSF/1 on Alpha, which requires we
return a proper errno, not an unchanged brk value. */
- if (is_error(mapped_addr)) {
- return -TARGET_ENOMEM;
- }
+ return -TARGET_ENOMEM;
#endif
-
- if (!is_error(mapped_addr)) {
- target_brk = new_brk;
- }
+ /* For everything else, return the previous break. */
return target_brk;
}
return 0;
}
+static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
+ abi_ulong target_fds_addr,
+ int n)
+{
+ if (target_fds_addr) {
+ if (copy_from_user_fdset(fds, target_fds_addr, n))
+ return -TARGET_EFAULT;
+ *fds_ptr = fds;
+ } else {
+ *fds_ptr = NULL;
+ }
+ return 0;
+}
+
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
const fd_set *fds,
int n)
}
#endif
+#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
/* do_select() must return target values and target errnos. */
static abi_long do_select(int n,
abi_ulong rfd_addr, abi_ulong wfd_addr,
struct timeval tv, *tv_ptr;
abi_long ret;
- if (rfd_addr) {
- if (copy_from_user_fdset(&rfds, rfd_addr, n))
- return -TARGET_EFAULT;
- rfds_ptr = &rfds;
- } else {
- rfds_ptr = NULL;
+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+ if (ret) {
+ return ret;
}
- if (wfd_addr) {
- if (copy_from_user_fdset(&wfds, wfd_addr, n))
- return -TARGET_EFAULT;
- wfds_ptr = &wfds;
- } else {
- wfds_ptr = NULL;
+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+ if (ret) {
+ return ret;
}
- if (efd_addr) {
- if (copy_from_user_fdset(&efds, efd_addr, n))
- return -TARGET_EFAULT;
- efds_ptr = &efds;
- } else {
- efds_ptr = NULL;
+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+ if (ret) {
+ return ret;
}
if (target_tv_addr) {
return ret;
}
+#endif
static abi_long do_pipe2(int host_pipe[], int flags)
{
#ifndef TARGET_ABI32
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
{
- abi_long ret;
+ abi_long ret = 0;
abi_ulong val;
int idx;
-
+
switch(code) {
case TARGET_ARCH_SET_GS:
case TARGET_ARCH_SET_FS:
idx = R_FS;
val = env->segs[idx].base;
if (put_user(val, addr, abi_ulong))
- return -TARGET_EFAULT;
+ ret = -TARGET_EFAULT;
break;
default:
ret = -TARGET_EINVAL;
break;
}
- return 0;
+ return ret;
}
#endif
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
- abi_long arg5, abi_long arg6)
+ abi_long arg5, abi_long arg6, abi_long arg7,
+ abi_long arg8)
{
abi_long ret;
struct stat st;
#endif
#ifdef TARGET_NR_pselect6
case TARGET_NR_pselect6:
- goto unimplemented_nowarn;
+ {
+ abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
+ fd_set rfds, wfds, efds;
+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+ struct timespec ts, *ts_ptr;
+
+ /*
+ * The 6th arg is actually two args smashed together,
+ * so we cannot use the C library.
+ */
+ sigset_t set;
+ struct {
+ sigset_t *set;
+ size_t size;
+ } sig, *sig_ptr;
+
+ abi_ulong arg_sigset, arg_sigsize, *arg7;
+ target_sigset_t *target_sigset;
+
+ n = arg1;
+ rfd_addr = arg2;
+ wfd_addr = arg3;
+ efd_addr = arg4;
+ ts_addr = arg5;
+
+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+ if (ret) {
+ goto fail;
+ }
+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+ if (ret) {
+ goto fail;
+ }
+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+ if (ret) {
+ goto fail;
+ }
+
+ /*
+ * This takes a timespec, and not a timeval, so we cannot
+ * use the do_select() helper ...
+ */
+ if (ts_addr) {
+ if (target_to_host_timespec(&ts, ts_addr)) {
+ goto efault;
+ }
+ ts_ptr = &ts;
+ } else {
+ ts_ptr = NULL;
+ }
+
+ /* Extract the two packed args for the sigset */
+ if (arg6) {
+ sig_ptr = &sig;
+ sig.size = _NSIG / 8;
+
+ arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
+ if (!arg7) {
+ goto efault;
+ }
+ arg_sigset = tswapl(arg7[0]);
+ arg_sigsize = tswapl(arg7[1]);
+ unlock_user(arg7, arg6, 0);
+
+ if (arg_sigset) {
+ sig.set = &set;
+ target_sigset = lock_user(VERIFY_READ, arg_sigset,
+ sizeof(*target_sigset), 1);
+ if (!target_sigset) {
+ goto efault;
+ }
+ target_to_host_sigset(&set, target_sigset);
+ unlock_user(target_sigset, arg_sigset, 0);
+ } else {
+ sig.set = NULL;
+ }
+ } else {
+ sig_ptr = NULL;
+ }
+
+ ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
+ ts_ptr, sig_ptr));
+
+ if (!is_error(ret)) {
+ if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
+ goto efault;
+ if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
+ goto efault;
+ if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
+ goto efault;
+
+ if (ts_addr && host_to_target_timespec(ts_addr, &ts))
+ goto efault;
+ }
+ }
+ break;
#endif
case TARGET_NR_symlink:
{
#endif
#ifdef TARGET_NR_syscall
case TARGET_NR_syscall:
- ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
- break;
+ ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8, 0);
+ break;
#endif
case TARGET_NR_wait4:
{
case TARGET_NR_osf_sigprocmask:
{
abi_ulong mask;
- int how = arg1;
+ int how;
sigset_t set, oldset;
switch(arg1) {
}
mask = arg2;
target_to_host_old_sigset(&set, &mask);
- sigprocmask(arg1, &set, &oldset);
+ sigprocmask(how, &set, &oldset);
host_to_target_old_sigset(&mask, &oldset);
ret = mask;
}
#if defined(TARGET_NR_sync_file_range)
case TARGET_NR_sync_file_range:
#if TARGET_ABI_BITS == 32
+#if defined(TARGET_MIPS)
+ ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
+ target_offset64(arg5, arg6), arg7));
+#else
ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
target_offset64(arg4, arg5), arg6));
+#endif /* !TARGET_MIPS */
#else
ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
#endif
TaskState *ts = env->opaque;
/* Allocate the heap using sbrk. */
if (!ts->heap_limit) {
- long ret;
+ abi_ulong ret;
uint32_t size;
uint32_t base;
/* Try a big heap, and reduce the size if that fails. */
for (;;) {
ret = do_brk(base + size);
- if (ret != -1)
+ if (ret >= (base + size)) {
break;
+ }
size >>= 1;
}
ts->heap_limit = base + size;
#include "json-streamer.h"
#include "json-parser.h"
#include "osdep.h"
-#include "exec-all.h"
+#include "cpu.h"
#ifdef CONFIG_SIMPLE_TRACE
#include "trace.h"
#endif
return i;
}
- error_report("qemu: Unsupported NIC model: %s", nd->model);
+ error_report("Unsupported NIC model: %s", nd->model);
return -1;
}
qemu_opt_get(opts, "connect") ||
qemu_opt_get(opts, "mcast") ||
qemu_opt_get(opts, "localaddr")) {
- error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n");
+ error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=");
return -1;
}
qemu_opt_get(opts, "connect") ||
qemu_opt_get(opts, "mcast") ||
qemu_opt_get(opts, "localaddr")) {
- error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n");
+ error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=");
return -1;
}
qemu_opt_get(opts, "listen") ||
qemu_opt_get(opts, "mcast") ||
qemu_opt_get(opts, "localaddr")) {
- error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n");
+ error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=");
return -1;
}
_fullpath(resolved_path, path, _MAX_PATH);
return resolved_path;
}
-
-#define PRId64 "I64d"
-#define PRIx64 "I64x"
-#define PRIu64 "I64u"
-#define PRIo64 "I64o"
#endif
/* FIXME: Remove NEED_CPU_H. */
/*
* Print an error message to current monitor if we have one, else to stderr.
+ * Format arguments like sprintf(). The result should not contain
+ * newlines.
* Prepend the current location and append a newline.
* It's wrong to call this in a QMP monitor. Use qerror_report() there.
*/
fmt = optarg;
break;
case 'e':
- error_report("qemu-img: option -e is deprecated, please use \'-o "
+ error_report("option -e is deprecated, please use \'-o "
"encryption\' instead!");
return 1;
case '6':
- error_report("qemu-img: option -6 is deprecated, please use \'-o "
+ error_report("option -6 is deprecated, please use \'-o "
"compat6\' instead!");
return 1;
case 'o':
compress = 1;
break;
case 'e':
- error_report("qemu-img: option -e is deprecated, please use \'-o "
+ error_report("option -e is deprecated, please use \'-o "
"encryption\' instead!");
return 1;
case '6':
- error_report("qemu-img: option -6 is deprecated, please use \'-o "
+ error_report("option -6 is deprecated, please use \'-o "
"compat6\' instead!");
return 1;
case 'o':
if (snapshot_name != NULL) {
if (bs_n > 1) {
- error_report("No support for concatenating multiple snapshot\n");
+ error_report("No support for concatenating multiple snapshot");
ret = -1;
goto out;
}
if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
- error_report("Failed to load snapshot\n");
+ error_report("Failed to load snapshot");
ret = -1;
goto out;
}
}
#endif
+static inline bool cpu_has_work(CPUState *env)
+{
+ /* Here we are checking to see if the CPU should wake up from HALT.
+ We will have gotten into this state only for WTINT from PALmode. */
+ /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
+ asleep even if (some) interrupts have been asserted. For now,
+ assume that if a CPU really wants to stay asleep, it will mask
+ interrupts at the chipset level, which will prevent these bits
+ from being set in the first place. */
+ return env->interrupt_request & (CPU_INTERRUPT_HARD
+ | CPU_INTERRUPT_TIMER
+ | CPU_INTERRUPT_SMP
+ | CPU_INTERRUPT_MCHK);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
#endif /* !defined (__CPU_ALPHA_H__) */
#define FP_STATUS (env->fp_status)
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- /* Here we are checking to see if the CPU should wake up from HALT.
- We will have gotten into this state only for WTINT from PALmode. */
- /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
- asleep even if (some) interrupts have been asserted. For now,
- assume that if a CPU really wants to stay asleep, it will mask
- interrupts at the chipset level, which will prevent these bits
- from being set in the first place. */
- return env->interrupt_request & (CPU_INTERRUPT_HARD
- | CPU_INTERRUPT_TIMER
- | CPU_INTERRUPT_SMP
- | CPU_INTERRUPT_MCHK);
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
#endif /* !defined (__ALPHA_EXEC_H__) */
#include <stdio.h>
#include "cpu.h"
-#include "exec-all.h"
#include "softfloat.h"
uint64_t cpu_alpha_load_fpcr (CPUState *env)
{
env->exception_index = excp;
env->error_code = error;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static void do_restore_state(void *retaddr)
env->exception_index = excp;
env->error_code = error;
do_restore_state(GETPC());
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
if (unlikely(ret != 0)) {
do_restore_state(retaddr);
/* Exception index and error code are already set */
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
#include <stdio.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "host-utils.h"
#include "tcg-op.h"
}
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request &
+ (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->regs[15] = tb->pc;
+}
+
#endif
register struct CPUARMState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request &
- (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB));
-}
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
void raise_exception(int);
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->regs[15] = tb->pc;
-}
-
#include <string.h>
#include "cpu.h"
-#include "exec-all.h"
#include "gdbstub.h"
#include "helper.h"
#include "qemu-common.h"
void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
{
env->exception_index = EXCP_HLT;
env->halted = 1;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(exception)(uint32_t excp)
{
env->exception_index = excp;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
uint32_t HELPER(cpsr_read)(void)
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
#define cpu_list cris_cpu_list
void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
#endif
register struct CPUCRISState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
#include "config.h"
#include "cpu.h"
#include "mmu.h"
-#include "exec-all.h"
#include "host-utils.h"
#include "config.h"
#include "cpu.h"
#include "mmu.h"
-#include "exec-all.h"
#ifdef DEBUG
#define D(x) x
helper_top_evaluate_flags();
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_tlb_flush_pid(uint32_t pid)
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "helper.h"
return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
}
+#undef EAX
+#define EAX (env->regs[R_EAX])
+#undef ECX
+#define ECX (env->regs[R_ECX])
+#undef EDX
+#define EDX (env->regs[R_EDX])
+#undef EBX
+#define EBX (env->regs[R_EBX])
+#undef ESP
+#define ESP (env->regs[R_ESP])
+#undef EBP
+#define EBP (env->regs[R_EBP])
+#undef ESI
+#define ESI (env->regs[R_ESI])
+#undef EDI
+#define EDI (env->regs[R_EDI])
+#undef EIP
+#define EIP (env->eip)
+#define DF (env->df)
+
+#define CC_SRC (env->cc_src)
+#define CC_DST (env->cc_dst)
+#define CC_OP (env->cc_op)
+
+/* float macros */
+#define FT0 (env->ft0)
+#define ST0 (env->fpregs[env->fpstt].d)
+#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
+#define ST1 ST(1)
+
/* translate.c */
void optimize_flags_init(void);
#include "hw/apic.h"
#endif
+static inline bool cpu_has_work(CPUState *env)
+{
+ return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->eflags & IF_MASK)) ||
+ (env->interrupt_request & (CPU_INTERRUPT_NMI |
+ CPU_INTERRUPT_INIT |
+ CPU_INTERRUPT_SIPI |
+ CPU_INTERRUPT_MCE));
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->eip = tb->pc - tb->cs_base;
+}
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
uint64_t status, uint64_t mcg_status, uint64_t addr,
uint64_t misc, int flags);
+/* op_helper.c */
+void do_interrupt(CPUState *env);
+void do_interrupt_x86_hardirq(CPUState *env, int intno, int is_hw);
+
+void do_smm_enter(CPUState *env1);
+
+void svm_check_intercept(CPUState *env1, uint32_t type);
+
+uint32_t cpu_cc_compute_all(CPUState *env1, int op);
+
#endif /* CPU_I386_H */
#include "qemu-common.h"
#include "qemu-log.h"
-#undef EAX
-#define EAX (env->regs[R_EAX])
-#undef ECX
-#define ECX (env->regs[R_ECX])
-#undef EDX
-#define EDX (env->regs[R_EDX])
-#undef EBX
-#define EBX (env->regs[R_EBX])
-#undef ESP
-#define ESP (env->regs[R_ESP])
-#undef EBP
-#define EBP (env->regs[R_EBP])
-#undef ESI
-#define ESI (env->regs[R_ESI])
-#undef EDI
-#define EDI (env->regs[R_EDI])
-#undef EIP
-#define EIP (env->eip)
-#define DF (env->df)
-
-#define CC_SRC (env->cc_src)
-#define CC_DST (env->cc_dst)
-#define CC_OP (env->cc_op)
-
-/* float macros */
-#define FT0 (env->ft0)
-#define ST0 (env->fpregs[env->fpstt].d)
-#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
-#define ST1 ST(1)
-
#include "cpu.h"
-#include "exec-all.h"
/* op_helper.c */
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw);
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip);
void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
void QEMU_NORETURN raise_exception(int exception_index);
void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv);
-void do_smm_enter(void);
/* n must be a constant to be efficient */
static inline target_long lshift(target_long x, int n)
#include "helper.h"
-static inline void svm_check_intercept(uint32_t type)
-{
- helper_svm_check_intercept_param(type, 0);
-}
-
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
(eflags & update_mask) | 0x2;
}
-static inline int cpu_has_work(CPUState *env)
-{
- return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK)) ||
- (env->interrupt_request & (CPU_INTERRUPT_NMI |
- CPU_INTERRUPT_INIT |
- CPU_INTERRUPT_SIPI |
- CPU_INTERRUPT_MCE));
-}
-
/* load efer and update the corresponding hflags. XXX: do consistency
checks with cpuid bits ? */
static inline void cpu_load_efer(CPUState *env, uint64_t val)
if (env->efer & MSR_EFER_SVME)
env->hflags |= HF_SVME_MASK;
}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->eip = tb->pc - tb->cs_base;
-}
-
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "qemu-common.h"
#include "kvm.h"
#ifndef CONFIG_USER_ONLY
#include "hw/pc.h"
#include "hw/isa.h"
-#include "exec-all.h"
+#include "cpu.h"
#include "kvm.h"
static const VMStateDescription vmstate_segment = {
#include <math.h>
#include "exec.h"
-#include "exec-all.h"
#include "host-utils.h"
#include "ioport.h"
{
env->exception_index = EXCP_SYSCALL;
env->exception_next_eip = env->eip + next_eip_addend;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#else
void helper_syscall(int next_eip_addend)
env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
}
+#if defined(CONFIG_USER_ONLY)
/* fake user mode interrupt */
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip)
+static void do_interrupt_user(int intno, int is_int, int error_code,
+ target_ulong next_eip)
{
SegmentCache *dt;
target_ulong ptr;
EIP = next_eip;
}
-#if !defined(CONFIG_USER_ONLY)
+#else
+
static void handle_even_inj(int intno, int is_int, int error_code,
int is_hw, int rm)
{
* the int instruction. next_eip is the EIP value AFTER the interrupt
* instruction. It is only relevant if is_int is TRUE.
*/
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
+static void do_interrupt_all(int intno, int is_int, int error_code,
+ target_ulong next_eip, int is_hw)
{
if (qemu_loglevel_mask(CPU_LOG_INT)) {
if ((env->cr[0] & CR0_PE_MASK)) {
#endif
}
+void do_interrupt(CPUState *env1)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+#if defined(CONFIG_USER_ONLY)
+ /* if user mode only, we simulate a fake exception
+ which will be handled outside the cpu execution
+ loop */
+ do_interrupt_user(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip);
+ /* successfully delivered */
+ env->old_exception = -1;
+#else
+ /* simulate a real cpu exception. On i386, it can
+ trigger new exceptions, but we do not handle
+ double or triple faults yet. */
+ do_interrupt_all(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip, 0);
+ /* successfully delivered */
+ env->old_exception = -1;
+#endif
+ env = saved_env;
+}
+
+void do_interrupt_x86_hardirq(CPUState *env1, int intno, int is_hw)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(intno, 0, 0, 0, is_hw);
+ env = saved_env;
+}
+
/* This should come from sysemu.h - if we could include it here... */
void qemu_system_reset_request(void);
env->error_code = error_code;
env->exception_is_int = is_int;
env->exception_next_eip = env->eip + next_eip_addend;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
/* shortcuts to generate exceptions */
#if defined(CONFIG_USER_ONLY)
-void do_smm_enter(void)
+void do_smm_enter(CPUState *env1)
{
}
#define SMM_REVISION_ID 0x00020000
#endif
-void do_smm_enter(void)
+void do_smm_enter(CPUState *env1)
{
target_ulong sm_state;
SegmentCache *dt;
int i, offset;
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
cpu_x86_update_cr4(env, 0);
env->dr[7] = 0x00000400;
CC_OP = CC_OP_EFLAGS;
+ env = saved_env;
}
void helper_rsm(void)
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_hlt(int next_eip_addend)
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_reset_rf(void)
{
}
+void svm_check_intercept(CPUState *env1, uint32_t type)
+{
+}
+
void helper_svm_check_io(uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
env->exception_next_eip = -1;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
/* XXX: is it always correct ? */
- do_interrupt(vector, 0, 0, 0, 1);
+ do_interrupt_all(vector, 0, 0, 0, 1);
break;
case SVM_EVTINJ_TYPE_NMI:
env->exception_index = EXCP02_NMI;
env->exception_is_int = 0;
env->exception_next_eip = EIP;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
- cpu_loop_exit();
+ cpu_loop_exit(env);
break;
case SVM_EVTINJ_TYPE_EXEPT:
env->exception_index = vector;
env->exception_is_int = 0;
env->exception_next_eip = -1;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
- cpu_loop_exit();
+ cpu_loop_exit(env);
break;
case SVM_EVTINJ_TYPE_SOFT:
env->exception_index = vector;
env->exception_is_int = 1;
env->exception_next_eip = EIP;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
- cpu_loop_exit();
+ cpu_loop_exit(env);
break;
}
qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index, env->error_code);
}
}
+void svm_check_intercept(CPUState *env1, uint32_t type)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ helper_svm_check_intercept_param(type, 0);
+ env = saved_env;
+}
+
void helper_svm_check_io(uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
env->error_code = 0;
env->old_exception = -1;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#endif
}
}
+uint32_t cpu_cc_compute_all(CPUState *env1, int op)
+{
+ CPUState *saved_env;
+ uint32_t ret;
+
+ saved_env = env;
+ env = env1;
+ ret = helper_cc_compute_all(op);
+ env = saved_env;
+ return ret;
+}
+
uint32_t helper_cc_compute_c(int op)
{
switch (op) {
#include <signal.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
*cs_base = 0;
*flags = 0;
}
+
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
#endif
register struct CPULM32State *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
-
-static inline int cpu_has_work(CPUState *env)
-{
- return env->interrupt_request & CPU_INTERRUPT_HARD;
-}
static inline int cpu_halted(CPUState *env)
{
}
return EXCP_HALTED;
}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "host-utils.h"
int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_hlt(void)
{
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_wcsr_im(uint32_t im)
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
#include <assert.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "helper.h"
#include "tcg-op.h"
CPUM68KState *cpu_m68k_init(const char *cpu_model);
int cpu_m68k_exec(CPUM68KState *s);
void cpu_m68k_close(CPUM68KState *s);
-void do_interrupt(int is_hw);
+void do_interrupt(CPUState *env1);
+void do_interrupt_m68k_hardirq(CPUState *env1);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
| ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
#endif
register struct CPUM68KState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & (CPU_INTERRUPT_HARD));
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "qemu-common.h"
#include "gdbstub.h"
#if defined(CONFIG_USER_ONLY)
-void do_interrupt(int is_hw)
+void do_interrupt(CPUState *env1)
+{
+ env1->exception_index = -1;
+}
+
+void do_interrupt_m68k_hardirq(CPUState *env1)
{
- env->exception_index = -1;
}
#else
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
env->aregs[7] = sp + 8;
}
-void do_interrupt(int is_hw)
+static void do_interrupt_all(int is_hw)
{
uint32_t sp;
uint32_t fmt;
}
env->halted = 1;
env->exception_index = EXCP_HLT;
- cpu_loop_exit();
+ cpu_loop_exit(env);
return;
}
if (env->exception_index >= EXCP_TRAP0
env->pc = ldl_kernel(env->vbr + vector);
}
+void do_interrupt(CPUState *env1)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(0);
+ env = saved_env;
+}
+
+void do_interrupt_m68k_hardirq(CPUState *env1)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(1);
+ env = saved_env;
+}
#endif
static void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(raise_exception)(uint32_t tt)
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
int is_asi, int size);
#endif
+
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->sregs[SR_PC] = tb->pc;
+}
+
#endif
register struct CPUMBState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->sregs[SR_PC] = tb->pc;
-}
-
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#include "host-utils.h"
#define D(x)
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#define D(x)
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
void helper_raise_exception(uint32_t index)
{
env->exception_index = index;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_debug(void)
#include <assert.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "helper.h"
env->tls_value = newtls;
}
+static inline int cpu_has_work(CPUState *env)
+{
+ int has_work = 0;
+
+ /* It is implementation dependent if non-enabled interrupts
+ wake-up the CPU, however most of the implementations only
+ check for interrupts that can be taken. */
+ if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ cpu_mips_hw_interrupts_pending(env)) {
+ has_work = 1;
+ }
+
+ return has_work;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->active_tc.PC = tb->pc;
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
+}
+
#endif /* !defined (__MIPS_CPU_H__) */
register struct CPUMIPSState *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- int has_work = 0;
-
- /* It is implementation dependent if non-enabled interrupts
- wake-up the CPU, however most of the implementations only
- check for interrupts that can be taken. */
- if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_mips_hw_interrupts_pending(env)) {
- has_work = 1;
- }
-
- return has_work;
-}
-
static inline void compute_hflags(CPUState *env)
{
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
}
}
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->active_tc.PC = tb->pc;
- env->hflags &= ~MIPS_HFLAG_BMASK;
- env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
-}
-
#endif /* !defined(__QEMU_MIPS_EXEC_H__) */
#include <signal.h>
#include "cpu.h"
-#include "exec-all.h"
enum {
TLBRET_DIRTY = -4,
#include "hw/hw.h"
#include "hw/boards.h"
-#include "exec-all.h"
+#include "cpu.h"
static void save_tc(QEMUFile *f, TCState *tc)
{
#endif
env->exception_index = exception;
env->error_code = error_code;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_raise_exception (uint32_t exception)
lladdr = cpu_mips_translate_address(env, address, rw);
if (lladdr == -1LL) {
- cpu_loop_exit();
+ cpu_loop_exit(env);
} else {
return lladdr;
}
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
extern void (*cpu_ppc_hypercall)(CPUState *);
+static inline bool cpu_has_work(CPUState *env)
+{
+ return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->nip = tb->pc;
+}
+
#endif /* !defined (__CPU_PPC_H__) */
#include "dyngen-exec.h"
#include "cpu.h"
-#include "exec-all.h"
register struct CPUPPCState *env asm(AREG0);
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- return (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD));
-}
-
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->nip = tb->pc;
-}
-
#endif /* !defined (__PPC_H__) */
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "helper_regs.h"
#include "qemu-common.h"
#include "kvm.h"
#endif
env->exception_index = exception;
env->error_code = error_code;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_raise_exception (uint32_t exception)
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
cpu_interrupt(env, CPU_INTERRUPT_HARD);
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->psw.mask & PSW_MASK_EXT);
+}
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
+{
+ env->psw.addr = tb->pc;
+}
+
#endif
#include "config.h"
#include "cpu.h"
-#include "exec-all.h"
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-static inline int cpu_has_work(CPUState *env)
-{
- return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->psw.mask & PSW_MASK_EXT));
-}
-
static inline void regs_to_env(void)
{
}
static inline void env_to_regs(void)
{
}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
-{
- env->psw.addr = tb->pc;
-}
-
#include <string.h>
#include "cpu.h"
-#include "exec-all.h"
#include "gdbstub.h"
#include "qemu-common.h"
#include "qemu-timer.h"
#include "helpers.h"
#include <string.h>
#include "kvm.h"
-#include <linux/kvm.h>
#include "qemu-timer.h"
+#ifdef CONFIG_KVM
+#include <linux/kvm.h>
+#endif
/*****************************************************************************/
/* Softmmu support */
cpu_restore_state(tb, env, pc);
}
}
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
{
HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp);
env->exception_index = excp;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#ifndef CONFIG_USER_ONLY
void HELPER(load_psw)(uint64_t mask, uint64_t addr)
{
load_psw(env, mask, addr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static void program_interrupt(CPUState *env, uint32_t code, int ilc)
qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
if (kvm_enabled()) {
+#ifdef CONFIG_KVM
kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
+#endif
} else {
env->int_pgm_code = code;
env->int_pgm_ilc = ilc;
env->exception_index = EXCP_PGM;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
}
}
if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
dest |= a1 & ~TARGET_PAGE_MASK;
if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
src |= a2 & ~TARGET_PAGE_MASK;
#endif
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
| (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
}
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+ env->flags = tb->flags;
+}
+
#endif /* _CPU_SH4_H */
register struct CPUSH4State *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
-
-static inline int cpu_has_work(CPUState *env)
-{
- return (env->interrupt_request & CPU_INTERRUPT_HARD);
-}
#ifndef CONFIG_USER_ONLY
#include "softmmu_exec.h"
#endif
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
- env->flags = tb->flags;
-}
-
#endif /* _EXEC_SH4_H */
#include <signal.h>
#include "cpu.h"
-#include "exec-all.h"
#include "hw/sh_intc.h"
#if defined(CONFIG_USER_ONLY)
if (ret) {
/* now we have a real cpu fault */
cpu_restore_state_from_retaddr(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
{
env->exception_index = index;
cpu_restore_state_from_retaddr(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_raise_illegal_instruction(void)
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_sleep(uint32_t next_pc)
env->in_sleep = 1;
env->exception_index = EXCP_HLT;
env->pc = next_pc;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void helper_trapa(uint32_t tra)
if (cause & enable) {
cpu_restore_state_from_retaddr(retaddr);
env->exception_index = 0x120;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
}
}
//#define SH4_SINGLE_STEP
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
uint32_t mmuregs[32];
uint64_t mxccdata[4];
uint64_t mxccregs[8];
+ uint32_t mmubpctrv, mmubpctrc, mmubpctrs;
+ uint64_t mmubpaction;
uint64_t mmubpregs[4];
uint64_t prom_addr;
#endif
void cpu_put_ccr(CPUState *env1, target_ulong val);
target_ulong cpu_get_cwp64(CPUState *env1);
void cpu_put_cwp64(CPUState *env1, int cwp);
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate);
#endif
int cpu_cwp_inc(CPUState *env1, int cwp);
int cpu_cwp_dec(CPUState *env1, int cwp);
#define cpu_signal_handler cpu_sparc_signal_handler
#define cpu_list sparc_cpu_list
-#define CPU_SAVE_VERSION 6
+#define CPU_SAVE_VERSION 7
/* MMU modes definitions */
#if defined (TARGET_SPARC64)
#endif
}
+/* helper.c */
+void do_interrupt(CPUState *env);
+
+static inline bool cpu_has_work(CPUState *env1)
+{
+ return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
+ cpu_interrupts_enabled(env1);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+ env->npc = tb->cs_base;
+}
+
#endif
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-/* op_helper.c */
-void do_interrupt(CPUState *env);
-
-static inline int cpu_has_work(CPUState *env1)
-{
- return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_interrupts_enabled(env1);
-}
-
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
- env->npc = tb->cs_base;
-}
-
#endif
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "qemu-common.h"
//#define DEBUG_MMU
}
#endif
+#ifdef TARGET_SPARC64
+#ifdef DEBUG_PCALL
+static const char * const excp_names[0x80] = {
+ [TT_TFAULT] = "Instruction Access Fault",
+ [TT_TMISS] = "Instruction Access MMU Miss",
+ [TT_CODE_ACCESS] = "Instruction Access Error",
+ [TT_ILL_INSN] = "Illegal Instruction",
+ [TT_PRIV_INSN] = "Privileged Instruction",
+ [TT_NFPU_INSN] = "FPU Disabled",
+ [TT_FP_EXCP] = "FPU Exception",
+ [TT_TOVF] = "Tag Overflow",
+ [TT_CLRWIN] = "Clean Windows",
+ [TT_DIV_ZERO] = "Division By Zero",
+ [TT_DFAULT] = "Data Access Fault",
+ [TT_DMISS] = "Data Access MMU Miss",
+ [TT_DATA_ACCESS] = "Data Access Error",
+ [TT_DPROT] = "Data Protection Error",
+ [TT_UNALIGNED] = "Unaligned Memory Access",
+ [TT_PRIV_ACT] = "Privileged Action",
+ [TT_EXTINT | 0x1] = "External Interrupt 1",
+ [TT_EXTINT | 0x2] = "External Interrupt 2",
+ [TT_EXTINT | 0x3] = "External Interrupt 3",
+ [TT_EXTINT | 0x4] = "External Interrupt 4",
+ [TT_EXTINT | 0x5] = "External Interrupt 5",
+ [TT_EXTINT | 0x6] = "External Interrupt 6",
+ [TT_EXTINT | 0x7] = "External Interrupt 7",
+ [TT_EXTINT | 0x8] = "External Interrupt 8",
+ [TT_EXTINT | 0x9] = "External Interrupt 9",
+ [TT_EXTINT | 0xa] = "External Interrupt 10",
+ [TT_EXTINT | 0xb] = "External Interrupt 11",
+ [TT_EXTINT | 0xc] = "External Interrupt 12",
+ [TT_EXTINT | 0xd] = "External Interrupt 13",
+ [TT_EXTINT | 0xe] = "External Interrupt 14",
+ [TT_EXTINT | 0xf] = "External Interrupt 15",
+};
+#endif
+
+void do_interrupt(CPUState *env)
+{
+ int intno = env->exception_index;
+ trap_state *tsptr;
+
+#ifdef DEBUG_PCALL
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
+ static int count;
+ const char *name;
+
+ if (intno < 0 || intno >= 0x180) {
+ name = "Unknown";
+ } else if (intno >= 0x100) {
+ name = "Trap Instruction";
+ } else if (intno >= 0xc0) {
+ name = "Window Fill";
+ } else if (intno >= 0x80) {
+ name = "Window Spill";
+ } else {
+ name = excp_names[intno];
+ if (!name) {
+ name = "Unknown";
+ }
+ }
+
+ qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
+ " SP=%016" PRIx64 "\n",
+ count, name, intno,
+ env->pc,
+ env->npc, env->regwptr[6]);
+ log_cpu_state(env, 0);
+#if 0
+ {
+ int i;
+ uint8_t *ptr;
+
+ qemu_log(" code=");
+ ptr = (uint8_t *)env->pc;
+ for (i = 0; i < 16; i++) {
+ qemu_log(" %02x", ldub(ptr + i));
+ }
+ qemu_log("\n");
+ }
+#endif
+ count++;
+ }
+#endif
+#if !defined(CONFIG_USER_ONLY)
+ if (env->tl >= env->maxtl) {
+ cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
+ " Error state", env->exception_index, env->tl, env->maxtl);
+ return;
+ }
+#endif
+ if (env->tl < env->maxtl - 1) {
+ env->tl++;
+ } else {
+ env->pstate |= PS_RED;
+ if (env->tl < env->maxtl) {
+ env->tl++;
+ }
+ }
+ tsptr = cpu_tsptr(env);
+
+ tsptr->tstate = (cpu_get_ccr(env) << 32) |
+ ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
+ cpu_get_cwp64(env);
+ tsptr->tpc = env->pc;
+ tsptr->tnpc = env->npc;
+ tsptr->tt = intno;
+
+ switch (intno) {
+ case TT_IVEC:
+ cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
+ break;
+ case TT_TFAULT:
+ case TT_DFAULT:
+ case TT_TMISS ... TT_TMISS + 3:
+ case TT_DMISS ... TT_DMISS + 3:
+ case TT_DPROT ... TT_DPROT + 3:
+ cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
+ break;
+ default:
+ cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
+ break;
+ }
+
+ if (intno == TT_CLRWIN) {
+ cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
+ } else if ((intno & 0x1c0) == TT_SPILL) {
+ cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
+ } else if ((intno & 0x1c0) == TT_FILL) {
+ cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
+ }
+ env->tbr &= ~0x7fffULL;
+ env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
+ env->pc = env->tbr;
+ env->npc = env->pc + 4;
+ env->exception_index = -1;
+}
+#else
+#ifdef DEBUG_PCALL
+static const char * const excp_names[0x80] = {
+ [TT_TFAULT] = "Instruction Access Fault",
+ [TT_ILL_INSN] = "Illegal Instruction",
+ [TT_PRIV_INSN] = "Privileged Instruction",
+ [TT_NFPU_INSN] = "FPU Disabled",
+ [TT_WIN_OVF] = "Window Overflow",
+ [TT_WIN_UNF] = "Window Underflow",
+ [TT_UNALIGNED] = "Unaligned Memory Access",
+ [TT_FP_EXCP] = "FPU Exception",
+ [TT_DFAULT] = "Data Access Fault",
+ [TT_TOVF] = "Tag Overflow",
+ [TT_EXTINT | 0x1] = "External Interrupt 1",
+ [TT_EXTINT | 0x2] = "External Interrupt 2",
+ [TT_EXTINT | 0x3] = "External Interrupt 3",
+ [TT_EXTINT | 0x4] = "External Interrupt 4",
+ [TT_EXTINT | 0x5] = "External Interrupt 5",
+ [TT_EXTINT | 0x6] = "External Interrupt 6",
+ [TT_EXTINT | 0x7] = "External Interrupt 7",
+ [TT_EXTINT | 0x8] = "External Interrupt 8",
+ [TT_EXTINT | 0x9] = "External Interrupt 9",
+ [TT_EXTINT | 0xa] = "External Interrupt 10",
+ [TT_EXTINT | 0xb] = "External Interrupt 11",
+ [TT_EXTINT | 0xc] = "External Interrupt 12",
+ [TT_EXTINT | 0xd] = "External Interrupt 13",
+ [TT_EXTINT | 0xe] = "External Interrupt 14",
+ [TT_EXTINT | 0xf] = "External Interrupt 15",
+ [TT_TOVF] = "Tag Overflow",
+ [TT_CODE_ACCESS] = "Instruction Access Error",
+ [TT_DATA_ACCESS] = "Data Access Error",
+ [TT_DIV_ZERO] = "Division By Zero",
+ [TT_NCP_INSN] = "Coprocessor Disabled",
+};
+#endif
+
+void do_interrupt(CPUState *env)
+{
+ int cwp, intno = env->exception_index;
+
+#ifdef DEBUG_PCALL
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
+ static int count;
+ const char *name;
+
+ if (intno < 0 || intno >= 0x100) {
+ name = "Unknown";
+ } else if (intno >= 0x80) {
+ name = "Trap Instruction";
+ } else {
+ name = excp_names[intno];
+ if (!name) {
+ name = "Unknown";
+ }
+ }
+
+ qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
+ count, name, intno,
+ env->pc,
+ env->npc, env->regwptr[6]);
+ log_cpu_state(env, 0);
+#if 0
+ {
+ int i;
+ uint8_t *ptr;
+
+ qemu_log(" code=");
+ ptr = (uint8_t *)env->pc;
+ for (i = 0; i < 16; i++) {
+ qemu_log(" %02x", ldub(ptr + i));
+ }
+ qemu_log("\n");
+ }
+#endif
+ count++;
+ }
+#endif
+#if !defined(CONFIG_USER_ONLY)
+ if (env->psret == 0) {
+ cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
+ env->exception_index);
+ return;
+ }
+#endif
+ env->psret = 0;
+ cwp = cpu_cwp_dec(env, env->cwp - 1);
+ cpu_set_cwp(env, cwp);
+ env->regwptr[9] = env->pc;
+ env->regwptr[10] = env->npc;
+ env->psrps = env->psrs;
+ env->psrs = 1;
+ env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
+ env->pc = env->tbr;
+ env->npc = env->pc + 4;
+ env->exception_index = -1;
+
+#if !defined(CONFIG_USER_ONLY)
+ /* IRQ acknowledgment */
+ if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
+ env->qemu_irq_ack(env->irq_manager, intno);
+ }
+#endif
+}
+#endif
+
void cpu_reset(CPUSPARCState *env)
{
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
#include "hw/boards.h"
#include "qemu-timer.h"
-#include "exec-all.h"
+#include "cpu.h"
void cpu_save(QEMUFile *f, void *opaque)
{
/* MMU */
for (i = 0; i < 32; i++)
qemu_put_be32s(f, &env->mmuregs[i]);
+ for (i = 0; i < 4; i++) {
+ qemu_put_be64s(f, &env->mxccdata[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ qemu_put_be64s(f, &env->mxccregs[i]);
+ }
+ qemu_put_be32s(f, &env->mmubpctrv);
+ qemu_put_be32s(f, &env->mmubpctrc);
+ qemu_put_be32s(f, &env->mmubpctrs);
+ qemu_put_be64s(f, &env->mmubpaction);
+ for (i = 0; i < 4; i++) {
+ qemu_put_be64s(f, &env->mmubpregs[i]);
+ }
#else
qemu_put_be64s(f, &env->lsu);
for (i = 0; i < 16; i++) {
/* MMU */
for (i = 0; i < 32; i++)
qemu_get_be32s(f, &env->mmuregs[i]);
+ for (i = 0; i < 4; i++) {
+ qemu_get_be64s(f, &env->mxccdata[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ qemu_get_be64s(f, &env->mxccregs[i]);
+ }
+ qemu_get_be32s(f, &env->mmubpctrv);
+ qemu_get_be32s(f, &env->mmubpctrc);
+ qemu_get_be32s(f, &env->mmubpctrs);
+ qemu_get_be64s(f, &env->mmubpaction);
+ for (i = 0; i < 4; i++) {
+ qemu_get_be64s(f, &env->mmubpregs[i]);
+ }
#else
qemu_get_be64s(f, &env->lsu);
for (i = 0; i < 16; i++) {
static void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(raise_exception)(int tt)
case 0x31: // Turbosparc RAM snoop
case 0x32: // Turbosparc page table descriptor diagnostic
case 0x39: /* data cache diagnostic register */
- case 0x4c: /* SuperSPARC MMU Breakpoint Action register */
ret = 0;
break;
case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
ret);
}
break;
+ case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ ret = env->mmubpctrv;
+ break;
+ case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ ret = env->mmubpctrc;
+ break;
+ case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ ret = env->mmubpctrs;
+ break;
+ case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ ret = env->mmubpaction;
+ break;
case 8: /* User code access, XXX */
default:
do_unassigned_access(addr, 0, 0, asi, size);
// descriptor diagnostic
case 0x36: /* I-cache flash clear */
case 0x37: /* D-cache flash clear */
- case 0x4c: /* breakpoint action */
break;
case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
{
env->mmuregs[reg]);
}
break;
+ case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ env->mmubpctrv = val & 0xffffffff;
+ break;
+ case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ env->mmubpctrc = val & 0x3;
+ break;
+ case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ env->mmubpctrs = val & 0x3;
+ break;
+ case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ env->mmubpaction = val & 0x1fff;
+ break;
case 8: /* User code access, XXX */
case 9: /* Supervisor code access, XXX */
default:
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#ifndef TARGET_SPARC64
#endif
}
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ change_pstate(new_pstate);
+ env = saved_env;
+}
+
void helper_wrpil(target_ulong new_pil)
{
#if !defined(CONFIG_USER_ONLY)
#endif
#ifdef TARGET_SPARC64
-#ifdef DEBUG_PCALL
-static const char * const excp_names[0x80] = {
- [TT_TFAULT] = "Instruction Access Fault",
- [TT_TMISS] = "Instruction Access MMU Miss",
- [TT_CODE_ACCESS] = "Instruction Access Error",
- [TT_ILL_INSN] = "Illegal Instruction",
- [TT_PRIV_INSN] = "Privileged Instruction",
- [TT_NFPU_INSN] = "FPU Disabled",
- [TT_FP_EXCP] = "FPU Exception",
- [TT_TOVF] = "Tag Overflow",
- [TT_CLRWIN] = "Clean Windows",
- [TT_DIV_ZERO] = "Division By Zero",
- [TT_DFAULT] = "Data Access Fault",
- [TT_DMISS] = "Data Access MMU Miss",
- [TT_DATA_ACCESS] = "Data Access Error",
- [TT_DPROT] = "Data Protection Error",
- [TT_UNALIGNED] = "Unaligned Memory Access",
- [TT_PRIV_ACT] = "Privileged Action",
- [TT_EXTINT | 0x1] = "External Interrupt 1",
- [TT_EXTINT | 0x2] = "External Interrupt 2",
- [TT_EXTINT | 0x3] = "External Interrupt 3",
- [TT_EXTINT | 0x4] = "External Interrupt 4",
- [TT_EXTINT | 0x5] = "External Interrupt 5",
- [TT_EXTINT | 0x6] = "External Interrupt 6",
- [TT_EXTINT | 0x7] = "External Interrupt 7",
- [TT_EXTINT | 0x8] = "External Interrupt 8",
- [TT_EXTINT | 0x9] = "External Interrupt 9",
- [TT_EXTINT | 0xa] = "External Interrupt 10",
- [TT_EXTINT | 0xb] = "External Interrupt 11",
- [TT_EXTINT | 0xc] = "External Interrupt 12",
- [TT_EXTINT | 0xd] = "External Interrupt 13",
- [TT_EXTINT | 0xe] = "External Interrupt 14",
- [TT_EXTINT | 0xf] = "External Interrupt 15",
-};
-#endif
-
trap_state* cpu_tsptr(CPUState* env)
{
return &env->ts[env->tl & MAXTL_MASK];
}
-
-void do_interrupt(CPUState *env)
-{
- int intno = env->exception_index;
- trap_state* tsptr;
-
-#ifdef DEBUG_PCALL
- if (qemu_loglevel_mask(CPU_LOG_INT)) {
- static int count;
- const char *name;
-
- if (intno < 0 || intno >= 0x180)
- name = "Unknown";
- else if (intno >= 0x100)
- name = "Trap Instruction";
- else if (intno >= 0xc0)
- name = "Window Fill";
- else if (intno >= 0x80)
- name = "Window Spill";
- else {
- name = excp_names[intno];
- if (!name)
- name = "Unknown";
- }
-
- qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
- " SP=%016" PRIx64 "\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
- log_cpu_state(env, 0);
-#if 0
- {
- int i;
- uint8_t *ptr;
-
- qemu_log(" code=");
- ptr = (uint8_t *)env->pc;
- for(i = 0; i < 16; i++) {
- qemu_log(" %02x", ldub(ptr + i));
- }
- qemu_log("\n");
- }
-#endif
- count++;
- }
-#endif
-#if !defined(CONFIG_USER_ONLY)
- if (env->tl >= env->maxtl) {
- cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
- " Error state", env->exception_index, env->tl, env->maxtl);
- return;
- }
-#endif
- if (env->tl < env->maxtl - 1) {
- env->tl++;
- } else {
- env->pstate |= PS_RED;
- if (env->tl < env->maxtl)
- env->tl++;
- }
- tsptr = cpu_tsptr(env);
-
- tsptr->tstate = (get_ccr() << 32) |
- ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
- get_cwp64();
- tsptr->tpc = env->pc;
- tsptr->tnpc = env->npc;
- tsptr->tt = intno;
-
- switch (intno) {
- case TT_IVEC:
- change_pstate(PS_PEF | PS_PRIV | PS_IG);
- break;
- case TT_TFAULT:
- case TT_DFAULT:
- case TT_TMISS ... TT_TMISS + 3:
- case TT_DMISS ... TT_DMISS + 3:
- case TT_DPROT ... TT_DPROT + 3:
- change_pstate(PS_PEF | PS_PRIV | PS_MG);
- break;
- default:
- change_pstate(PS_PEF | PS_PRIV | PS_AG);
- break;
- }
-
- if (intno == TT_CLRWIN) {
- set_cwp(cwp_dec(env->cwp - 1));
- } else if ((intno & 0x1c0) == TT_SPILL) {
- set_cwp(cwp_dec(env->cwp - env->cansave - 2));
- } else if ((intno & 0x1c0) == TT_FILL) {
- set_cwp(cwp_inc(env->cwp + 1));
- }
- env->tbr &= ~0x7fffULL;
- env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
- env->pc = env->tbr;
- env->npc = env->pc + 4;
- env->exception_index = -1;
-}
-#else
-#ifdef DEBUG_PCALL
-static const char * const excp_names[0x80] = {
- [TT_TFAULT] = "Instruction Access Fault",
- [TT_ILL_INSN] = "Illegal Instruction",
- [TT_PRIV_INSN] = "Privileged Instruction",
- [TT_NFPU_INSN] = "FPU Disabled",
- [TT_WIN_OVF] = "Window Overflow",
- [TT_WIN_UNF] = "Window Underflow",
- [TT_UNALIGNED] = "Unaligned Memory Access",
- [TT_FP_EXCP] = "FPU Exception",
- [TT_DFAULT] = "Data Access Fault",
- [TT_TOVF] = "Tag Overflow",
- [TT_EXTINT | 0x1] = "External Interrupt 1",
- [TT_EXTINT | 0x2] = "External Interrupt 2",
- [TT_EXTINT | 0x3] = "External Interrupt 3",
- [TT_EXTINT | 0x4] = "External Interrupt 4",
- [TT_EXTINT | 0x5] = "External Interrupt 5",
- [TT_EXTINT | 0x6] = "External Interrupt 6",
- [TT_EXTINT | 0x7] = "External Interrupt 7",
- [TT_EXTINT | 0x8] = "External Interrupt 8",
- [TT_EXTINT | 0x9] = "External Interrupt 9",
- [TT_EXTINT | 0xa] = "External Interrupt 10",
- [TT_EXTINT | 0xb] = "External Interrupt 11",
- [TT_EXTINT | 0xc] = "External Interrupt 12",
- [TT_EXTINT | 0xd] = "External Interrupt 13",
- [TT_EXTINT | 0xe] = "External Interrupt 14",
- [TT_EXTINT | 0xf] = "External Interrupt 15",
- [TT_TOVF] = "Tag Overflow",
- [TT_CODE_ACCESS] = "Instruction Access Error",
- [TT_DATA_ACCESS] = "Data Access Error",
- [TT_DIV_ZERO] = "Division By Zero",
- [TT_NCP_INSN] = "Coprocessor Disabled",
-};
-#endif
-
-void do_interrupt(CPUState *env)
-{
- int cwp, intno = env->exception_index;
-
-#ifdef DEBUG_PCALL
- if (qemu_loglevel_mask(CPU_LOG_INT)) {
- static int count;
- const char *name;
-
- if (intno < 0 || intno >= 0x100)
- name = "Unknown";
- else if (intno >= 0x80)
- name = "Trap Instruction";
- else {
- name = excp_names[intno];
- if (!name)
- name = "Unknown";
- }
-
- qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
- log_cpu_state(env, 0);
-#if 0
- {
- int i;
- uint8_t *ptr;
-
- qemu_log(" code=");
- ptr = (uint8_t *)env->pc;
- for(i = 0; i < 16; i++) {
- qemu_log(" %02x", ldub(ptr + i));
- }
- qemu_log("\n");
- }
-#endif
- count++;
- }
-#endif
-#if !defined(CONFIG_USER_ONLY)
- if (env->psret == 0) {
- cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
- env->exception_index);
- return;
- }
-#endif
- env->psret = 0;
- cwp = cwp_dec(env->cwp - 1);
- set_cwp(cwp);
- env->regwptr[9] = env->pc;
- env->regwptr[10] = env->npc;
- env->psrps = env->psrs;
- env->psrs = 1;
- env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
- env->pc = env->tbr;
- env->npc = env->pc + 4;
- env->exception_index = -1;
-
-#if !defined(CONFIG_USER_ONLY)
- /* IRQ acknowledgment */
- if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
- env->qemu_irq_ack(env->irq_manager, intno);
- }
-#endif
-}
#endif
#if !defined(CONFIG_USER_ONLY)
ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
if (ret) {
cpu_restore_state2(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "helper.h"
#include "tcg-op.h"
void do_interrupt(CPUState *);
void switch_mode(CPUState_UniCore32 *, int);
+static inline bool cpu_has_work(CPUState *env)
+{
+ return env->interrupt_request &
+ (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
#endif /* __CPU_UC32_H__ */
register struct CPUState_UniCore32 *env asm(AREG0);
#include "cpu.h"
-#include "exec-all.h"
static inline void env_to_regs(void)
{
{
}
-static inline int cpu_has_work(CPUState *env)
-{
- return env->interrupt_request &
- (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
-}
-
static inline int cpu_halted(CPUState *env)
{
if (!env->halted) {
#include <string.h>
#include "cpu.h"
-#include "exec-all.h"
#include "gdbstub.h"
#include "helper.h"
#include "qemu-common.h"
void HELPER(exception)(uint32_t excp)
{
env->exception_index = excp;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
static target_ulong asr_read(void)
#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"
tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
tcg_add_target_add_op_defs(arm_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
static void tcg_target_qemu_prologue(TCGContext *s)
{
- /* There is no need to save r7, it is used to store the address
- of the env structure and is not modified by GCC. */
+ /* Calling convention requires us to save r4-r11 and lr;
+ * save also r12 to maintain stack 8-alignment.
+ */
+
+ /* stmdb sp!, { r4 - r12, lr } */
+ tcg_out32(s, (COND_AL << 28) | 0x092d5ff0);
- /* stmdb sp!, { r4 - r6, r8 - r11, lr } */
- tcg_out32(s, (COND_AL << 28) | 0x092d4f70);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
- tcg_out_bx(s, COND_AL, TCG_REG_R0);
+ tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
tb_ret_addr = s->code_ptr;
- /* ldmia sp!, { r4 - r6, r8 - r11, pc } */
- tcg_out32(s, (COND_AL << 28) | 0x08bd8f70);
+ /* ldmia sp!, { r4 - r12, pc } */
+ tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0);
}
TCG_REG_R14,
TCG_REG_R15,
TCG_REG_R16,
- /* R17 is the global env, so no need to save. */
+ TCG_REG_R17, /* R17 is the global env. */
TCG_REG_R18
};
}
#endif
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+
/* Jump to TB, and adjust R18 to be the return address. */
- tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26));
+ tcg_out32(s, INSN_BLE_SR4 | INSN_R2(tcg_target_call_iarg_regs[1]));
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R18, TCG_REG_R31);
/* Restore callee saved registers. */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
tcg_add_target_add_op_defs(hppa_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
/* Pop and discard. This is 2 bytes smaller than the add. */
tcg_out_pop(s, TCG_REG_ECX);
} else if (stack_adjust != 0) {
- tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
+ tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
}
/* label2: */
TCG_REG_RBX,
TCG_REG_R12,
TCG_REG_R13,
- /* TCG_REG_R14, */ /* Currently used for the global env. */
+ TCG_REG_R14, /* Currently used for the global env. */
TCG_REG_R15,
#else
- /* TCG_REG_EBP, */ /* Currently used for the global env. */
+ TCG_REG_EBP, /* Currently used for the global env. */
TCG_REG_EBX,
TCG_REG_ESI,
TCG_REG_EDI,
/* TB prologue */
- /* Save all callee saved registers. */
- for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
- tcg_out_push(s, tcg_target_callee_save_regs[i]);
- }
-
- /* Reserve some stack space. */
+ /* Reserve some stack space, also for TCG temps. */
push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
push_size *= TCG_TARGET_REG_BITS / 8;
- frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
+ frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE +
+ CPU_TEMP_BUF_NLONGS * sizeof(long);
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
stack_addend = frame_size - push_size;
+ tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
+
+ /* Save all callee saved registers. */
+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+ tcg_out_push(s, tcg_target_callee_save_regs[i]);
+ }
+
tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+
/* jmp *tb. */
- tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]);
+ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
/* TB epilogue */
tb_ret_addr = s->code_ptr;
- tcg_out_addi(s, TCG_REG_ESP, stack_addend);
+ tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
tcg_out_pop(s, tcg_target_callee_save_regs[i]);
}
tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
tcg_add_target_add_op_defs(x86_op_defs);
}
tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34,
TCG_REG_R33, 32, 24, 0),
tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
- TCG_REG_B6, TCG_REG_R32, 0),
+ TCG_REG_B6, TCG_REG_R33, 0),
tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
TCG_REG_R32, TCG_REG_B0));
}
tcg_out_bundle(s, miB,
- tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+ tcg_opc_m48(TCG_REG_P0, OPC_MOV_I21,
+ TCG_REG_AREG0, TCG_REG_R32, 0),
tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
TCG_REG_R12, -frame_size, TCG_REG_R12),
tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
tcg_add_target_add_op_defs(ia64_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
};
static int tcg_target_callee_save_regs[] = {
-#if 0 /* used for the global env (TCG_AREG0), so no need to save */
- TCG_REG_S0,
-#endif
+ TCG_REG_S0, /* used for the global env (TCG_AREG0) */
TCG_REG_S1,
TCG_REG_S2,
TCG_REG_S3,
}
/* Call generated code */
- tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0);
- tcg_out_nop(s);
+ tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1]), 0);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
tb_ret_addr = s->code_ptr;
/* TB epilogue */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
tcg_add_target_add_op_defs(mips_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
- /* TCG_REG_R27, */ /* currently used for the global env, so no
- need to save */
+ TCG_REG_R27, /* currently used for the global env */
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
}
#endif
- tcg_out32 (s, MTSPR | RS (3) | CTR);
+ tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+ tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
tcg_out32 (s, BCCTR | BO_ALWAYS);
tb_ret_addr = s->code_ptr;
#endif
tcg_add_target_add_op_defs(ppc_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
- /* TCG_REG_R27, */ /* currently used for the global env, so no
- need to save */
+ TCG_REG_R27, /* currently used for the global env */
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
}
#endif
- tcg_out32 (s, MTSPR | RS (3) | CTR);
+ tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+ tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
tcg_out32 (s, BCCTR | BO_ALWAYS);
/* Epilogue */
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
tcg_add_target_add_op_defs (ppc_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
tcg_add_target_add_op_defs(s390_op_defs);
+ tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
}
static void tcg_target_qemu_prologue(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
}
- /* br %r2 (go to TB) */
- tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+ /* br %r3 (go to TB) */
+ tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
tb_ret_addr = s->code_ptr;
/* Generate global QEMU prologue and epilogue code */
static void tcg_target_qemu_prologue(TCGContext *s)
{
+ tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
+ CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
- INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
+ INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
+ CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
+ tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
INSN_RS2(TCG_REG_G0));
- tcg_out_nop(s);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
}
#if defined(CONFIG_SOFTMMU)
instructions */
#define NO_CPU_IO_DEFS
#include "cpu.h"
-#include "exec-all.h"
#include "tcg-op.h"
#include "elf.h"
{
TCGTemp *ts;
ts = &s->temps[temp];
- s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
- if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
+#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
+ s->current_frame_offset = (s->current_frame_offset +
+ (tcg_target_long)sizeof(tcg_target_long) - 1) &
+ ~(sizeof(tcg_target_long) - 1);
+#endif
+ if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
+ s->frame_end) {
tcg_abort();
+ }
ts->mem_offset = s->current_frame_offset;
ts->mem_reg = s->frame_reg;
ts->mem_allocated = 1;
- s->current_frame_offset += sizeof(tcg_target_long);
+ s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
}
/* free register 'reg' by spilling the corresponding temporary if necessary */
nb_regs = nb_params;
/* assign stack slots first */
- /* XXX: preallocate call stack */
call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
~(TCG_TARGET_STACK_ALIGN - 1);
allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
if (allocate_args) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
+ /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
+ preallocate call stack */
+ tcg_abort();
}
stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
}
tcg_out_op(s, opc, &func_arg, &const_func_arg);
-
- if (allocate_args) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
- }
/* assign output registers and emit moves if needed */
for(i = 0; i < nb_oargs; i++) {
extern uint8_t code_gen_prologue[];
#if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
-#define tcg_qemu_tb_exec(tb_ptr) \
- ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
+#define tcg_qemu_tb_exec(env, tb_ptr) \
+ ((long REGPARM __attribute__ ((longcall)) (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
#else
-#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
+#define tcg_qemu_tb_exec(env, tb_ptr) \
+ ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
#endif
#define NO_CPU_IO_DEFS
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "tcg.h"
#include "qemu-timer.h"
void cpu_gen_init(void)
{
tcg_context_init(&tcg_ctx);
- tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
- CPU_TEMP_BUF_NLONGS * sizeof(long));
}
/* return non zero if the very first instruction is invalid so that
#include "config-host.h"
+/* This needs to be before jpeglib.h line because of conflict with
+ INT32 definitions between jmorecfg.h (included by jpeglib.h) and
+ Win32 basetsd.h (included by windows.h). */
+#include "qemu-common.h"
+
#ifdef CONFIG_VNC_PNG
+/* The following define is needed by pngconf.h. Otherwise it won't compile,
+ because setjmp.h was already included by qemu-common.h. */
+#define PNG_SKIP_SETJMP_CHECK
#include <png.h>
#endif
#ifdef CONFIG_VNC_JPEG
#include <jpeglib.h>
#endif
-#include "qemu-common.h"
-
#include "bswap.h"
#include "qint.h"
#include "vnc.h"
//#define DEBUG_SIGNAL
+static void exception_action(CPUState *env1)
+{
#if defined(TARGET_I386)
-#define EXCEPTION_ACTION \
- raise_exception_err(env->exception_index, env->error_code)
+ raise_exception_err(env1->exception_index, env1->error_code);
#else
-#define EXCEPTION_ACTION \
- cpu_loop_exit()
+ cpu_loop_exit(env1);
#endif
+}
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- EXCEPTION_ACTION;
+ exception_action(env);
/* never comes here */
return 1;
#include "config.h"
-#include "exec-all.h"
+#include "cpu.h"
#include "qemu-common.h"
#include "cpu-common.h"
#include "xen-mapcache.h"