common-obj-$(CONFIG_ADS7846) += ads7846.o
common-obj-$(CONFIG_MAX111X) += max111x.o
common-obj-$(CONFIG_DS1338) += ds1338.o
-common-obj-y += i2c.o i2c-addressable.o smbus.o smbus_eeprom.o
+common-obj-y += i2c.o smbus.o smbus_eeprom.o
common-obj-y += eeprom93xx.o
common-obj-y += scsi-disk.o cdrom.o
common-obj-y += scsi-generic.o scsi-bus.o
hw-obj-$(CONFIG_PCSPK) += pcspk.o
hw-obj-$(CONFIG_PCKBD) += pckbd.o
hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
-hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o
+hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
hw-obj-$(CONFIG_FDC) += fdc.o
hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
obj-arm-y += gumstix.o
-obj-arm-y += zaurus.o ide/microdrive.o tosa.o tc6393xb.o
+obj-arm-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o
obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \
omap_gpio.o omap_intc.o omap_uart.o
obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \
obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
obj-arm-y += syborg_virtio.o
-#########################################################
-# Samsung additional hardware
-obj-arm-y += pl192.o pl330.o
-obj-arm-y += s5pc1xx.o s5pc1xx_pmu.o s5pc1xx_onedram.o s5pc1xx_usb_otg.o
-obj-arm-y += s5pc1xx_i2c.o s5pc1xx_gpio.o s5pc1xx_i2c_gpio.o s5pc1xx_spi.o
-obj-arm-y += s5pc1xx_clk.o s5pc1xx_rtc.o s5pc1xx_pwm.o s5pc1xx_wdt.o s5pc1xx_st.o
-obj-arm-y += s5pc1xx_nand.o s5pc1xx_onenand.o s5pc1xx_srom.o s5pc1xx_mmc.o
-obj-arm-y += s5pc1xx_uart.o s5pc1xx_tsadc.o s5pc1xx_keyif.o s5pc1xx_lcd.o
-obj-arm-y += s5pc1xx_ac97.o s5pc1xx_pcm.o s5pc1xx_spdif.o s5pc1xx_i2s.o
-obj-arm-y += s5pc1xx_jpeg.o
-obj-arm-y += qt602240_ts.o mcs5000_tk.o wm8994.o ak8973.o
-obj-arm-y += smb380.o
-obj-arm-y += ide/mmio.o
-
-# USB layer
-obj-arm-$(CONFIG_USB_OHCI) += usb-ohci.o
-
-#ifeq ($(HOST_USB), libusb)
-#LIBS += $(LIBUSB_LIBS)
-#endif
-
-##########################################################
-# virtio, opengl for arm(dummy)
-obj-arm-y += helper_gpi_dummy.o opengl_dummy.o
-##########################################################
-
-ifeq ($(TARGET_BASE_ARCH), arm)
-ifdef CONFIG_JPEG
-LIBS+=-lm -ljpeg
-CFLAGS+= $(VNC_JPEG_CFLAGS)
-endif
-ifdef CONFIG_FFMPEG
-LIBS+=-lavformat -lavcodec -lavutil -lswscale -lbz2
-CFLAGS+= $(FFMPEG_CFLAGS)
-endif
-
-ifdef CONFIG_GLES2
-CFLAGS+=-I$(DGLES2)/include
-LIBS+=-L$(DGLES2)/lib
-ifdef CONFIG_GLES2_STATIC
-LIBS+=-Wl,-Bstatic -lEGL -lGLESv2 -lOSMesa -Wl,-Bdynamic
-else
-LIBS+=-lEGL -lGLESv2
-endif
-ifndef CONFIG_WIN32
-LIBS+=-LX11 -ldl
-endif
-obj-arm-y += gles2.o gles2_calls.o gles1_calls.o
-endif # CONFIG_GLES2
-endif # TARGET_BASE_ARCH==arm
-
-#############################################################
-
obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
obj-sh4-y += ide/mmio.o
monitor.o: hmp-commands.h qmp-commands.h
-
$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS)
obj-y += $(addprefix ../, $(common-obj-y))
obj-y += $(addprefix ../libdis/, $(libdis-y))
obj-y += $(libobj-y)
obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
-obj-y += $(addprefix ../, $(trace-obj-y))
endif # CONFIG_SOFTMMU
+obj-y += $(addprefix ../, $(trace-obj-y))
obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
#$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
endif
# arm
-gles1_calls.o: gles1_calls.c gles2.h gles2_calls.h
-gles2_calls.o: gles2_calls.c gles2.h gles2_calls.h
-gles2.o: gles2.c gles2.h gles2_calls.h
+#gles1_calls.o: gles1_calls.c gles2.h gles2_calls.h
+#gles2_calls.o: gles2_calls.c gles2.h gles2_calls.h
+#gles2.o: gles2.c gles2.h gles2_calls.h
##########################################################
BlockDriver *drv)
{
int ret;
- int probed = 0;
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
/* Find the right image format driver */
if (!drv) {
ret = find_image_format(filename, &drv);
- probed = 1;
}
if (!drv) {
goto unlink_and_fail;
}
- bs->probed = probed;
-
/* If there is a backing file, use it */
if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
char backing_filename[PATH_MAX];
int fd, ret;
int prio = 0;
- if (strstart(filename, "/dev/cd", NULL))
- prio = 50;
-
fd = open(filename, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
goto out;
return 0;
}
-/* check for the user attempting to write something that looks like a
- block format header to the beginning of the image and fail out.
-*/
-static int check_for_block_signature(BlockDriverState *bs, const uint8_t *buf)
-{
- static const uint8_t signatures[][4] = {
- { 'Q', 'F', 'I', 0xfb }, /* qcow/qcow2 */
- { 'C', 'O', 'W', 'D' }, /* VMDK3 */
- { 'V', 'M', 'D', 'K' }, /* VMDK4 */
- { 'O', 'O', 'O', 'M' }, /* UML COW */
- {}
- };
- int i;
-
- for (i = 0; signatures[i][0] != 0; i++) {
- if (memcmp(buf, signatures[i], 4) == 0) {
- return 1;
- }
- }
-
- return 0;
-}
-
-static int check_write_unsafe(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- /* assume that if the user specifies the format explicitly, then assume
- that they will continue to do so and provide no safety net */
- if (!bs->probed) {
- return 0;
- }
-
- if (sector_num == 0 && nb_sectors > 0) {
- return check_for_block_signature(bs, buf);
- }
-
- return 0;
-}
-
static int raw_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
return bdrv_read(bs->file, sector_num, buf, nb_sectors);
}
-static int raw_write_scrubbed_bootsect(BlockDriverState *bs,
- const uint8_t *buf)
-{
- uint8_t bootsect[512];
-
- /* scrub the dangerous signature */
- memcpy(bootsect, buf, 512);
- memset(bootsect, 0, 4);
-
- return bdrv_write(bs->file, 0, bootsect, 1);
-}
-
static int raw_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
- if (check_write_unsafe(bs, sector_num, buf, nb_sectors)) {
- int ret;
-
- ret = raw_write_scrubbed_bootsect(bs, buf);
- if (ret < 0) {
- return ret;
- }
-
- ret = bdrv_write(bs->file, 1, buf + 512, nb_sectors - 1);
- if (ret < 0) {
- return ret;
- }
-
- return ret + 512;
- }
-
return bdrv_write(bs->file, sector_num, buf, nb_sectors);
}
return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
}
-typedef struct RawScrubberBounce
-{
- BlockDriverCompletionFunc *cb;
- void *opaque;
- QEMUIOVector qiov;
-} RawScrubberBounce;
-
-static void raw_aio_writev_scrubbed(void *opaque, int ret)
-{
- RawScrubberBounce *b = opaque;
-
- if (ret < 0) {
- b->cb(b->opaque, ret);
- } else {
- b->cb(b->opaque, ret + 512);
- }
-
- qemu_iovec_destroy(&b->qiov);
- qemu_free(b);
-}
-
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
- const uint8_t *first_buf;
- int first_buf_index = 0, i;
-
- /* This is probably being paranoid, but handle cases of zero size
- vectors. */
- for (i = 0; i < qiov->niov; i++) {
- if (qiov->iov[i].iov_len) {
- assert(qiov->iov[i].iov_len >= 512);
- first_buf_index = i;
- break;
- }
- }
-
- first_buf = qiov->iov[first_buf_index].iov_base;
-
- if (check_write_unsafe(bs, sector_num, first_buf, nb_sectors)) {
- RawScrubberBounce *b;
- int ret;
-
- /* write the first sector using sync I/O */
- ret = raw_write_scrubbed_bootsect(bs, first_buf);
- if (ret < 0) {
- return NULL;
- }
-
- /* adjust request to be everything but first sector */
-
- b = qemu_malloc(sizeof(*b));
- b->cb = cb;
- b->opaque = opaque;
-
- qemu_iovec_init(&b->qiov, qiov->nalloc);
- qemu_iovec_concat(&b->qiov, qiov, qiov->size);
-
- b->qiov.size -= 512;
- b->qiov.iov[first_buf_index].iov_base += 512;
- b->qiov.iov[first_buf_index].iov_len -= 512;
-
- return bdrv_aio_writev(bs->file, sector_num + 1, &b->qiov,
- nb_sectors - 1, raw_aio_writev_scrubbed, b);
- }
-
return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
}
static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
{
- uint32_t ret;
-
- if (sector_num < s->faked_sectors)
- ret = 0;
- else
- ret = (sector_num-s->faked_sectors)/s->sectors_per_cluster;
- return ret;
+ return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
}
static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
int encrypted; /* if true, the media is encrypted */
int valid_key; /* if true, a valid encryption key has been set */
int sg; /* if true, the device is a /dev/sg* */
- int probed; /* if true, format was probed automatically */
/* event callback when inserting/removing */
void (*change_cb)(void *opaque, int reason);
void *change_opaque;
vde=""
vnc_tls=""
vnc_sasl=""
-jpeg="yes"
vnc_jpeg=""
vnc_png=""
vnc_thread="no"
pkgversion=""
check_utests="no"
user_pie="no"
-gles2="no"
-gles2_static="no"
zero_malloc=""
trace_backend="nop"
trace_file="trace"
;;
--enable-jpeg) jpeg="yes"
;;
+
--disable-vnc-tls) vnc_tls="no"
;;
--enable-vnc-tls) vnc_tls="yes"
;;
--enable-docs) docs="yes"
;;
- --enable-gles2) gles2="yes"; gles2dir="/usr";
- ;;
- --disable-gles2) gles2="no";
- ;;
- --enable-gles2-static) gles2="yes"; gles2_static="yes" gles2dir="/usr";
- ;;
- --disable-gles2-static) gles2_static="no";
- ;;
- --gles2dir=*) gles2dir="$optarg"
- ;;
--disable-vhost-net) vhost_net="no"
;;
--enable-vhost-net) vhost_net="yes"
echo " --disable-sdl disable SDL"
echo " --enable-sdl enable SDL"
echo " --enable-cocoa enable COCOA (Mac OS X only)"
-echo " --disable-jpeg disable JPEG support"
-echo " --enable-jpeg enable JPEG support"
echo " --audio-drv-list=LIST set audio drivers list:"
echo " Available drivers: $audio_possible_drivers"
echo " --audio-card-list=LIST set list of emulated audio cards [$audio_card_list]"
echo " --kerneldir=PATH look for kernel includes in PATH"
echo " --enable-docs enable documentation build"
echo " --disable-docs disable documentation build"
-echo " --enable-gles2 ARM target: Enable OpenGL ES 2.0 hardware accelerator"
-echo " --enable-gles2-static ARM target: Link OpenGL ES 2.0 hardware accelerator statically"
-echo " --gles2dir=PATH prefix where dgles2 is installed"
echo " --disable-vhost-net disable vhost-net acceleration support"
echo " --enable-vhost-net enable vhost-net acceleration support"
echo " --enable-trace-backend=B Set trace backend"
fi
##########################################
-# JPEG detection
-if test "$jpeg" != "no"; then
+# VNC JPEG detection
+if test "$vnc_jpeg" != "no" ; then
cat > $TMPC <<EOF
#include <stdio.h>
#include <jpeglib.h>
int main(void) { struct jpeg_compress_struct s; jpeg_create_compress(&s); return 0; }
EOF
- jpeg_cflags=""
- jpeg_libs="-ljpeg"
- if compile_prog "$jpeg_cflags" "$jpeg_libs" ; then
- jpeg=yes
- if test "$vnc_jpeg" != "no"; then
- vnc_jpeg=yes
- fi
- libs_softmmu="$jpeg_libs $libs_softmmu"
+ vnc_jpeg_cflags=""
+ vnc_jpeg_libs="-ljpeg"
+ if compile_prog "$vnc_jpeg_cflags" "$vnc_jpeg_libs" ; then
+ vnc_jpeg=yes
+ libs_softmmu="$vnc_jpeg_libs $libs_softmmu"
else
- if test "$jpeg" = "yes" ; then
- feature_not_found "jpeg"
+ if test "$vnc_jpeg" = "yes" ; then
+ feature_not_found "vnc-jpeg"
fi
- jpeg=no
vnc_jpeg=no
fi
-elif test "$vnc_jpeg" != "no"; then
- echo
- echo "Error: VNC JPEG was requested but JPEG was disabled"
- echo "Please either enable JPEG with '--enable-jpeg' or disable VNC JPEG with '--disable-vnc-jpeg'."
- echo
- exit 1
fi
##########################################
echo "Cocoa support $cocoa"
fi
echo "SDL support $sdl"
-echo "JPEG support $jpeg"
echo "curses support $curses"
echo "curl support $curl"
echo "check support $check_utests"
echo "KVM support $kvm"
echo "fdt support $fdt"
echo "preadv support $preadv"
-echo "gles2 support $gles2"
-echo "gles2 static $gles2_static"
-echo "dgles2 prefix $gles2dir"
echo "fdatasync $fdatasync"
echo "madvise $madvise"
echo "posix_madvise $posix_madvise"
if test "$mixemu" = "yes" ; then
echo "CONFIG_MIXEMU=y" >> $config_host_mak
fi
-if test "$jpeg" = "yes" ; then
- echo "CONFIG_JPEG=y" >> $config_host_mak
- echo "JPEG_CFLAGS=$jpeg_cflags" >> $config_host_mak
-fi
if test "$vnc_tls" = "yes" ; then
echo "CONFIG_VNC_TLS=y" >> $config_host_mak
echo "VNC_TLS_CFLAGS=$vnc_tls_cflags" >> $config_host_mak
if test "$posix_madvise" = "yes" ; then
echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
fi
+
if test "$spice" = "yes" ; then
echo "CONFIG_SPICE=y" >> $config_host_mak
fi
-if test "$gles2" = "yes" ; then
- echo "CONFIG_GLES2=y" >> $config_host_mak
-if test "$gles2_static" = "yes" ; then
- echo "CONFIG_GLES2_STATIC=y" >> $config_host_mak
-fi
- echo "DGLES2=$gles2dir" >> $config_host_mak
-fi
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
/* in ms */
#define GUI_REFRESH_INTERVAL 30
-/* Keyboard events handlers should return zero if they handled the event */
-typedef int QEMUPutKBDEvent(void *opaque, int keycode);
+typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
} QEMUPutLEDEntry;
-typedef struct QEMUPutKbdEntry {
- char *qemu_put_kbd_name;
- QEMUPutKBDEvent *qemu_put_kbd_event;
- void *qemu_put_kbd_event_opaque;
- int index;
-
- QTAILQ_ENTRY(QEMUPutKbdEntry) node;
-} QEMUPutKbdEntry;
-
-QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
- void *opaque,
- const char *name);
-void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
-void qemu_activate_keyboard_event_handler(QEMUPutKbdEntry *entry);
+void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+void qemu_remove_kbd_event_handler(void);
+void qemu_add_ps2kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+void qemu_remove_ps2kbd_event_handler(void);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
void do_info_mice(Monitor *mon, QObject **ret_data);
void do_mouse_set(Monitor *mon, const QDict *qdict);
-void do_info_keyboard_print(Monitor *mon, const QObject *data);
-void do_info_keyboard(Monitor *mon, QObject **ret_data);
-int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data);
-
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
constants) */
#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
include pci.mak
CONFIG_GDBSTUB_XML=y
-CONFIG_USB_OHCI=y
-CONFIG_USB_EHCI=y
CONFIG_ISA_MMIO=y
CONFIG_NAND=y
CONFIG_ECC=y
0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-static int adb_kbd_put_keycode(void *opaque, int keycode)
+static void adb_kbd_put_keycode(void *opaque, int keycode)
{
ADBDevice *d = opaque;
KBDState *s = d->opaque;
s->wptr = 0;
s->count++;
}
- return 0;
}
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
register_savevm(NULL, "adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
target_phys_addr_t smp_priv_base;
int nb_cpus;
int board_id;
- int revision;
int (*atag_board)(struct arm_boot_info *info, void *p);
/* Used internally by arm_boot.c */
int is_linux;
cpu_physical_memory_write(p, atag_board_buf, atag_board_len);
p += atag_board_len;
}
- if (info->revision) {
- /* ATAG_REVISION */
- WRITE_WORD(p, 3);
- WRITE_WORD(p, 0x54410007);
- WRITE_WORD(p, info->revision);
- }
/* ATAG_END */
WRITE_WORD(p, 0);
WRITE_WORD(p, 0);
return bitbang_i2c_ret(i2c, data);
case SENDING_ACK:
+ i2c->state = RECEIVING_BIT7;
if (data != 0) {
DPRINTF("NACKED\n");
- i2c->state = STOPPED;
i2c_nack(i2c->bus);
} else {
- i2c->state = RECEIVING_BIT7;
DPRINTF("ACKED\n");
}
return bitbang_i2c_ret(i2c, 1);
struct QEMUMachine *next;
} QEMUMachine;
-int qemu_arch_is_arm(void);
int qemu_register_machine(QEMUMachine *m);
extern QEMUMachine *current_machine;
static const uint8_t broadcast_macaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- /* TODO: check multiple IA bit. */
- if (s->configuration[20] & BIT(6)) {
- missing("Multiple IA bit");
- return -1;
- }
-
if (s->configuration[8] & 0x80) {
/* CSMA is disabled. */
logout("%p received while CSMA is disabled\n", s);
static inline void set_rxint(ChannelState *s)
{
s->rxint = 1;
- if (!s->txint_under_svc) {
- s->rxint_under_svc = 1;
- if (s->chn == chn_a) {
+ /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
+ than chn_a rx/tx/special_condition service*/
+ s->rxint_under_svc = 1;
+ if (s->chn == chn_a) {
s->rregs[R_INTR] |= INTR_RXINTA;
if (s->wregs[W_MINTR] & MINTR_STATUSHI)
s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
else
s->rregs[R_IVEC] = IVEC_LORXINTB;
}
- }
- if (s->chn == chn_a)
- s->rregs[R_INTR] |= INTR_RXINTA;
- else
- s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
escc_update_irq(s);
}
1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
};
-static int sunkbd_event(void *opaque, int ch)
+static void sunkbd_event(void *opaque, int ch)
{
ChannelState *s = opaque;
int release = ch & 0x80;
case 58: // Caps lock press
s->caps_lock_mode ^= 1;
if (s->caps_lock_mode == 2)
- return 0; // Drop second press
+ return; // Drop second press
break;
case 69: // Num lock press
s->num_lock_mode ^= 1;
if (s->num_lock_mode == 2)
- return 0; // Drop second press
+ return; // Drop second press
break;
case 186: // Caps lock release
s->caps_lock_mode ^= 2;
if (s->caps_lock_mode == 3)
- return 0; // Drop first release
+ return; // Drop first release
break;
case 197: // Num lock release
s->num_lock_mode ^= 2;
if (s->num_lock_mode == 3)
- return 0; // Drop first release
+ return; // Drop first release
break;
case 0xe0:
s->e0_mode = 1;
- return 0;
+ return;
default:
break;
}
}
KBD_DPRINTF("Translated keycode %2.2x\n", ch);
put_queue(s, ch | release);
- return 0;
}
static void handle_kbd_command(ChannelState *s, int val)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
- "QEMU Sun Keyboard");
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
}
return 0;
/* onenand.c */
void onenand_base_update(void *opaque, target_phys_addr_t new);
void onenand_base_unmap(void *opaque);
-/* id = XXYYZZ (XX - Manufacturer, YY - device properties, ZZ - version)
- regshift = 1 in most cases
- page_size = 10 (for 1kB-page chips), 11 (for 2kB-page chips),
- 12 (for 4kB-page chips)
- data_buf = 2 in most cases */
-void *onenand_init(uint32_t id, int regshift, qemu_irq irq,
- int page_size, int data_buf);
+void *onenand_init(uint32_t id, int regshift, qemu_irq irq);
void *onenand_raw_otp(void *opaque);
-#define ONENAND_1KB_PAGE 10
-#define ONENAND_2KB_PAGE 11
-#define ONENAND_4KB_PAGE 12
-
/* ecc.c */
typedef struct {
uint8_t cp; /* Column parity */
/* lm832x.c */
void lm832x_key_event(i2c_slave *i2c, int key, int state);
-/* wm8994.c */
-void wm8994_data_req_set(DeviceState *dev, void (*data_req)(void *, int),
- void *opaque);
-void *wm8994_dac_buffer(DeviceState *dev, int samples);
-void wm8994_dac_dat(DeviceState *dev, uint32_t sample);
-void wm8994_dac_commit(DeviceState *dev);
-
#endif
typedef struct {
IDEBus bus;
int shift;
- int offset;
} MMIOState;
static void mmio_ide_reset(void *opaque)
static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
{
MMIOState *s = opaque;
- addr = (addr - s->offset) >> s->shift;
+ addr >>= s->shift;
if (addr & 7)
return ide_ioport_read(&s->bus, addr);
else
uint32_t val)
{
MMIOState *s = opaque;
- addr = (addr - s->offset) >> s->shift;
+ addr >>= s->shift;
if (addr & 7)
ide_ioport_write(&s->bus, addr, val);
else
ide_init2_with_non_qdev_drives(&s->bus, hd0, hd1, irq);
s->shift = shift;
- s->offset = membase & ~TARGET_PAGE_MASK;
mem1 = cpu_register_io_memory(mmio_ide_reads, mmio_ide_writes, s,
DEVICE_NATIVE_ENDIAN);
qemu_irq out[8];
} musicpal_key_state;
-static int musicpal_key_event(void *opaque, int keycode)
+static void musicpal_key_event(void *opaque, int keycode)
{
musicpal_key_state *s = opaque;
uint32_t event = 0;
if (keycode == KEYCODE_EXTENDED) {
s->kbd_extended = 1;
- return 0;
+ return;
}
if (s->kbd_extended) {
}
s->kbd_extended = 0;
- return 0;
}
static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
+ qemu_add_kbd_event_handler(musicpal_key_event, s);
return 0;
}
onenand_base_unmap,
(s->nand = onenand_init(0xec4800, 1,
omap2_gpio_in_get(s->cpu->gpif,
- N8X0_ONENAND_GPIO)[0],
- ONENAND_2KB_PAGE, 2)));
+ N8X0_ONENAND_GPIO)[0])));
otp_region = onenand_raw_otp(s->nand);
memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
#define RETU_KEYCODE 61 /* F3 */
-static int n800_key_event(void *opaque, int keycode)
+static void n800_key_event(void *opaque, int keycode)
{
struct n800_s *s = (struct n800_s *) opaque;
int code = s->keymap[keycode & 0x7f];
if (code == -1) {
if ((keycode & 0x7f) == RETU_KEYCODE)
retu_key_event(s->retu, !(keycode & 0x80));
- return 0;
+ return;
}
tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
- return 0;
}
static const int n800_keys[16] = {
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
+ qemu_add_kbd_event_handler(n800_key_event, s);
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
}
/* N810 Keyboard controller */
-static int n810_key_event(void *opaque, int keycode)
+static void n810_key_event(void *opaque, int keycode)
{
struct n800_s *s = (struct n800_s *) opaque;
int code = s->keymap[keycode & 0x7f];
if (code == -1) {
if ((keycode & 0x7f) == RETU_KEYCODE)
retu_key_event(s->retu, !(keycode & 0x80));
- return 0;
+ return;
}
lm832x_key_event(s->kbd, code, !(keycode & 0x80));
- return 0;
}
#define M 0
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
+ qemu_add_kbd_event_handler(n810_key_event, s);
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
#include "irq.h"
#include "blockdev.h"
+/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
+#define PAGE_SHIFT 11
+
+/* Fixed */
+#define BLOCK_SHIFT (PAGE_SHIFT + 6)
+
typedef struct {
uint32_t id;
int shift;
int secs_cur;
int blocks;
uint8_t *blockwp;
-
- int page_shift;
- int block_shift;
- int dbuf_num;
-
- int superload;
} OneNANDState;
enum {
void onenand_base_update(void *opaque, target_phys_addr_t new)
{
OneNANDState *s = (OneNANDState *) opaque;
- int buf_data_size = (0x7e50 << s->shift);
- int buf_boot_size = (0x0200 << s->shift);
- int slow_buf_size = buf_data_size % TARGET_PAGE_SIZE ?
- buf_data_size % TARGET_PAGE_SIZE :
- TARGET_PAGE_SIZE;
- int fast_buf_size = buf_data_size - slow_buf_size;
s->base = new;
/* XXX: We should use IO_MEM_ROMD but we broke it earlier...
* Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
* write boot commands. Also take note of the BWPS bit. */
- cpu_register_physical_memory(s->base, buf_boot_size, s->iomemtype);
-
- cpu_register_physical_memory(s->base + buf_boot_size,
- fast_buf_size,
- (s->ram + buf_boot_size) | IO_MEM_RAM);
-
- cpu_register_physical_memory_offset(s->base + buf_boot_size + fast_buf_size,
- slow_buf_size, s->iomemtype,
- buf_boot_size + fast_buf_size);
-
- if (s->iomemtype) {
+ cpu_register_physical_memory(s->base + (0x0000 << s->shift),
+ 0x0200 << s->shift, s->iomemtype);
+ cpu_register_physical_memory(s->base + (0x0200 << s->shift),
+ 0xbe00 << s->shift,
+ (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
+ if (s->iomemtype)
cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
- 0x4000 << s->shift, s->iomemtype,
- (0xc000 << s->shift));
- }
+ 0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
}
void onenand_base_unmap(void *opaque)
s->command = 0;
s->count = 1;
s->bufaddr = 0;
- s->config[0] = 0xc0c0;
+ s->config[0] = 0x40c0;
s->config[1] = 0x0000;
onenand_intr_update(s);
qemu_irq_raise(s->rdy);
s->bdrv_cur = s->bdrv;
s->current = s->image;
s->secs_cur = s->secs;
- s->superload = 0;
if (cold) {
/* Lock the whole flash */
if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
return 1;
memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
- } else if (sec + secn > s->secs_cur) {
+ } else if (sec + secn > s->secs_cur)
return 1;
- } else {
+ else
memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
- }
-
+
return 0;
}
return 1;
memcpy(buf + ((sec & 31) << 4), src, secn << 4);
return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0;
- } else if (sec + secn > s->secs_cur) {
+ } else if (sec + secn > s->secs_cur)
return 1;
- }
memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
-
+
return 0;
}
uint8_t buf[512];
memset(buf, 0xff, sizeof(buf));
- for (; num > 0; num--, sec++) {
+ for (; num > 0; num --, sec ++) {
if (onenand_prog_main(s, sec, 1, buf))
return 1;
if (onenand_prog_spare(s, sec, 1, buf))
((((s->addr[page] >> 2) & 0x3f) + \
(((s->addr[block] & 0xfff) | \
(s->addr[block] >> 15 ? \
- s->density_mask : 0)) << 6)) << (s->page_shift - 9));
+ s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
#define SETBUF_M() \
buf = (s->bufaddr & 8) ? \
s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0]; \
buf = (s->bufaddr & 8) ? \
s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \
buf += (s->bufaddr & 3) << 4;
-#define IS_SAMSUNG_ONENAND() (((s->id >> 16) & 0xff) == 0xEC)
switch (cmd) {
case 0x00: /* Load single/multiple sector data unit into buffer */
if (onenand_load_main(s, sec, s->count, buf))
s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
- if (IS_SAMSUNG_ONENAND()) {
- SETBUF_S()
- if (onenand_load_spare(s, sec, s->count, buf))
- s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
- }
+#if 0
+ SETBUF_S()
+ if (onenand_load_spare(s, sec, s->count, buf))
+ s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
+#endif
/* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
* or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
*/
s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
break;
- case 0x03: /* Superload */
- s->superload = 1;
- break;
case 0x13: /* Load single/multiple spare sector into buffer */
SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
if (onenand_prog_main(s, sec, s->count, buf))
s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
- if (IS_SAMSUNG_ONENAND()) {
- SETBUF_S()
- if (onenand_prog_spare(s, sec, s->count, buf))
- s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
- }
+#if 0
+ SETBUF_S()
+ if (onenand_prog_spare(s, sec, s->count, buf))
+ s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
+#endif
/* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
* or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
case 0x94: /* Block erase */
sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
(s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
- << (s->block_shift - 9);
- if (onenand_erase(s, sec, 1 << (s->block_shift - 9)))
+ << (BLOCK_SHIFT - 9);
+ if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
s->intstatus |= ONEN_INT;
s->bdrv_cur = NULL;
s->current = s->otp;
- s->secs_cur = 1 << (s->block_shift - 9);
+ s->secs_cur = 1 << (BLOCK_SHIFT - 9);
s->addr[ONEN_BUF_BLOCK] = 0;
s->otpmode = 1;
break;
{
OneNANDState *s = (OneNANDState *) opaque;
int offset = addr >> s->shift;
- int res = 0;
switch (offset) {
- case 0x0000 ... 0x804e:
+ case 0x0000 ... 0xc000:
return lduw_le_p(s->boot[0] + addr);
- case 0x804f:
- res = lduw_le_p(s->boot[0] + addr);
- if (s->superload) {
- onenand_command(s, 0x00); /* Read */
- }
- s->superload = 0;
- return res;
+
case 0xf000: /* Manufacturer ID */
return (s->id >> 16) & 0xff;
case 0xf001: /* Device ID */
case 0xf002: /* Version ID */
return (s->id >> 0) & 0xff;
case 0xf003: /* Data Buffer size */
- /* Number of buffers each of one page size measured in words */
- return s->dbuf_num << (s->page_shift - 1);
+ return 1 << PAGE_SHIFT;
case 0xf004: /* Boot Buffer size */
return 0x200;
case 0xf005: /* Amount of buffers */
- return 1 | (s->dbuf_num << 8);
+ return 1 | (2 << 8);
case 0xf006: /* Technology */
return 0;
return s->addr[offset - 0xf100];
case 0xf200: /* Start buffer */
- return (s->bufaddr << 8) |
- (s->count & (1 << (s->page_shift - 9)) ? 0 : s->count);
+ return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
case 0xf220: /* Command */
return s->command;
case 0xff02: /* ECC Result of spare area data */
case 0xff03: /* ECC Result of main area data */
case 0xff04: /* ECC Result of spare area data */
- /* Why we do ever need to care about ECC? There can't be any errors.
- * So return zero as a success status. */
- /* hw_error("%s: implement ECC\n", __FUNCTION__); */
+ hw_error("%s: imeplement ECC\n", __FUNCTION__);
return 0x0000;
}
return 0;
}
-static uint32_t onenand_read_32(void *opaque, target_phys_addr_t addr)
-{
- uint32_t res = onenand_read(opaque, addr) |
- (onenand_read(opaque, addr + 2) << 16);
- return res;
-}
-
-static void onenand_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+static void onenand_write(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
{
OneNANDState *s = (OneNANDState *) opaque;
int offset = addr >> s->shift;
if (value == 0x0000) {
SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
onenand_load_main(s, sec,
- 1 << (s->page_shift - 9), s->data[0][0]);
+ 1 << (PAGE_SHIFT - 9), s->data[0][0]);
s->addr[ONEN_BUF_PAGE] += 4;
s->addr[ONEN_BUF_PAGE] &= 0xff;
}
}
break;
- case 0x0200 ... 0x7fff:
- case 0x8010 ... 0x804f:
- stw_le_p(s->boot[0] + addr, (uint16_t)value);
- break;
-
case 0xf100 ... 0xf107: /* Start addresses */
s->addr[offset - 0xf100] = value;
break;
case 0xf200: /* Start buffer */
s->bufaddr = (value >> 8) & 0xf;
- if (s->page_shift == 12)
- s->count = (value & 7) ?: 8;
- else if (s->page_shift == 11)
+ if (PAGE_SHIFT == 11)
s->count = (value & 3) ?: 4;
- else if (s->page_shift == 10)
+ else if (PAGE_SHIFT == 10)
s->count = (value & 1) ?: 2;
break;
}
}
-static void onenand_write_32(void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- onenand_write(opaque, addr, value & 0xffff);
- onenand_write(opaque, addr + 2, value >> 16);
-}
-
static CPUReadMemoryFunc * const onenand_readfn[] = {
onenand_read, /* TODO */
onenand_read,
- onenand_read_32,
+ onenand_read,
};
static CPUWriteMemoryFunc * const onenand_writefn[] = {
onenand_write, /* TODO */
onenand_write,
- onenand_write_32,
+ onenand_write,
};
-void *onenand_init(uint32_t id, int regshift, qemu_irq irq,
- int page_size, int data_buf)
+void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
{
OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
uint32_t size = 1 << (24 + ((id >> 12) & 7));
void *ram;
- /* 12 for 4kB-page OneNAND, 11 for 2kB-page OneNAND ("2nd generation") and
- 10 for 1kB-page chips */
- s->page_shift = page_size;
- s->dbuf_num = data_buf;
-
- /* Fixed */
- s->block_shift = s->page_shift + 6;
s->shift = regshift;
s->intr = irq;
s->rdy = NULL;
s->id = id;
- s->blocks = size >> s->block_shift;
+ s->blocks = size >> BLOCK_SHIFT;
s->secs = size >> 9;
s->blockwp = qemu_malloc(s->blocks);
s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
0xff, size + (size >> 5));
else
s->bdrv = dinfo->bdrv;
- s->otp = memset(qemu_malloc((64 + 2) << s->page_shift),
- 0xff, (64 + 2) << s->page_shift);
+ s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
+ 0xff, (64 + 2) << PAGE_SHIFT);
s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift);
ram = qemu_get_ram_ptr(s->ram);
s->boot[0] = ram + (0x0000 << s->shift);
s->boot[1] = ram + (0x8000 << s->shift);
- s->data[0][0] = ram + ((0x0200 + (0 << (s->page_shift - 1))) << s->shift);
- s->data[0][1] = ram + ((0x8010 + (0 << (s->page_shift - 6))) << s->shift);
- if (s->page_shift < 12) {
- /* FIXME: what is here when page_shift IS 12? */
- s->data[1][0] =
- ram + ((0x0200 + (1 << (s->page_shift - 1))) << s->shift);
- s->data[1][1] =
- ram + ((0x8010 + (1 << (s->page_shift - 6))) << s->shift);
- }
+ s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
+ s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
+ s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
+ s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
onenand_reset(s, 1);
[0x39] = { 4, 1 }, /* Spc -> Centre */
};
-static int palmte_button_event(void *opaque, int keycode)
+static void palmte_button_event(void *opaque, int keycode)
{
struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
palmte_keymap[keycode & 0x7f].row,
palmte_keymap[keycode & 0x7f].column,
!(keycode & 0x80));
- return 0;
}
static void palmte_onoff_gpios(void *opaque, int line, int level)
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
+ qemu_add_kbd_event_handler(palmte_button_event, cpu);
palmte_gpio_setup(cpu);
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415
-#define PCI_DEVICE_ID_INTEL_82801D 0x24CD
#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
/* pl080.c */
void *pl080_init(uint32_t base, qemu_irq irq, int nchannels);
-/* pl192.c */
-DeviceState *pl192_init(target_phys_addr_t base,
- int instance, ...);
-void pl192_chain(void *first, void *next);
-
-/* pl330.c */
-DeviceState *pl330_init(target_phys_addr_t base,
- uint32_t instance, const uint32_t *cfg,
- qemu_irq *irqs, qemu_irq irq_abort);
-
/* arm_sysctl.c */
void arm_sysctl_init(uint32_t base, uint32_t sys_id, uint32_t proc_id);
bit 7 - 0 key pressed, 1 = key released
bits 6-0 - translated scancode set 2
*/
-static int ps2_put_keycode(void *opaque, int keycode)
+static void ps2_put_keycode(void *opaque, int keycode)
{
PS2KbdState *s = opaque;
keycode = ps2_raw_keycode[keycode & 0x7f];
}
ps2_queue(&s->common, keycode);
- return 0;
}
uint32_t ps2_read_data(void *opaque)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
+ qemu_add_ps2kbd_event_handler(ps2_put_keycode, s);
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
uint32_t kpkdi;
};
-static int pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode)
+static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode)
{
int row, col,rel;
if(!(kp->kpc & KPC_ME)) /* skip if not enabled */
- return 0;
+ return;
if(kp->kpc & KPC_AS || kp->kpc & KPC_ASACT) {
if(kp->kpc & KPC_AS)
row = kp->map[keycode].row;
col = kp->map[keycode].column;
if(row == -1 || col == -1)
- return 0;
+ return;
switch (col) {
case 0:
case 1:
} /* switch */
goto out;
}
- return 0;
+ return;
out:
if(kp->kpc & KPC_MIE) {
kp->kpc |= KPC_MI;
qemu_irq_raise(kp->irq);
}
- return 0;
+ return;
}
static uint32_t pxa2xx_keypad_read(void *opaque, target_phys_addr_t offset)
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp,
- "PXA keypad");
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
}
if (!info || info->no_user) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
error_printf_unless_qmp("Try with argument '?' for a list.\n");
- if( info )
- error_printf_unless_qmp("INFO OK.\n");
-
return NULL;
}
return NULL;
}
-static int next_block_unit[IF_COUNT];
-
-/* Get a block device. This should only be used for single-drive devices
- (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
- appropriate bus. */
-BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
-{
- int unit = next_block_unit[type]++;
- DriveInfo *dinfo;
-
- dinfo = drive_get(type, 0, unit);
- return dinfo ? dinfo->bdrv : NULL;
-}
-
-
-
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque)
{
#define QDEV_H
#include "hw.h"
-#include "blockdev.h"
#include "qemu-queue.h"
#include "qemu-char.h"
#include "qemu-option.h"
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
-BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type);
BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
/*** Device API. ***/
}
QUEUE_KEY((code & 0x7f) | (keycode & 0x80));
- return 0;
}
static void spitz_keyboard_tick(void *opaque)
s->keymap[spitz_keymap[i][j]] = (i << 4) | j;
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s,
- "Spitz keyboard");
s->kbdtimer = qemu_new_timer(vm_clock, spitz_keyboard_tick, s);
qdev_init_gpio_in(&dev->qdev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
int extension;
} gamepad_state;
-static int stellaris_gamepad_put_key(void * opaque, int keycode)
+static void stellaris_gamepad_put_key(void * opaque, int keycode)
{
gamepad_state *s = (gamepad_state *)opaque;
int i;
if (keycode == 0xe0 && !s->extension) {
s->extension = 0x80;
- return 0;
+ return;
}
down = (keycode & 0x80) == 0;
}
s->extension = 0;
- return 0;
}
static void stellaris_gamepad_save(QEMUFile *f, void *opaque)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
register_savevm(NULL, "stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
syborg_keyboard_write
};
-static int syborg_keyboard_event(void *opaque, int keycode)
+static void syborg_keyboard_event(void *opaque, int keycode)
{
SyborgKeyboardState *s = (SyborgKeyboardState *)opaque;
int slot;
if (keycode == 0xe0 && !s->extension_bit) {
DPRINTF("Extension bit\n");
s->extension_bit = 0x80;
- return 0;
+ return;
}
val = (keycode & 0x7f) | s->extension_bit;
if (keycode & 0x80)
}
syborg_keyboard_update(s);
- return 0;
}
static void syborg_keyboard_save(QEMUFile *f, void *opaque)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s);
register_savevm(&dev->qdev, "syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
uint8_t leds;
uint8_t key[16];
int32_t keys;
- int keyboard_grabbed;
- QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
usb_hid_changed(hs);
}
-static int usb_keyboard_event(void *opaque, int keycode)
+static void usb_keyboard_event(void *opaque, int keycode)
{
USBHIDState *hs = opaque;
USBKeyboardState *s = &hs->kbd;
if (hs->n == QUEUE_LENGTH) {
fprintf(stderr, "usb-kbd: warning: key event queue full\n");
- return 0;
+ return;
}
slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
s->keycodes[slot] = keycode;
usb_hid_changed(hs);
- return 0;
}
-static int usb_keyboard_process_keycode(USBHIDState *hs)
+static void usb_keyboard_process_keycode(USBHIDState *hs)
{
USBKeyboardState *s = &hs->kbd;
uint8_t hid_code, key;
int i, keycode, slot;
if (hs->n == 0) {
- return 0;
+ return;
}
slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
keycode = s->keycodes[slot];
switch (hid_code) {
case 0x00:
- return 0;
+ return;
case 0xe0:
if (s->modifiers & (1 << 9)) {
s->modifiers ^= 3 << 8;
usb_hid_changed(hs);
- return 0;
+ return;
}
case 0xe1 ... 0xe7:
if (keycode & (1 << 7)) {
s->modifiers &= ~(1 << (hid_code & 0x0f));
usb_hid_changed(hs);
- return 0;
+ return;
}
case 0xe8 ... 0xef:
s->modifiers |= 1 << (hid_code & 0x0f);
usb_hid_changed(hs);
- return 0;
+ return;
}
if (keycode & (1 << 7)) {
break;
}
if (i < 0)
- return 0;
+ return;
} else {
for (i = s->keys - 1; i >= 0; i --)
if (s->key[i] == hid_code)
if (s->keys < sizeof(s->key))
s->key[s->keys ++] = hid_code;
} else
- return 0;
+ return;
}
-
- usb_hid_changed(hs);
- return 0;
}
static inline int int_clamp(int val, int vmin, int vmax)
return 0;
usb_keyboard_process_keycode(hs);
-// if (!s->keyboard_grabbed) {
-// qemu_activate_keyboard_event_handler(s->eh_entry);
-// s->keyboard_grabbed = 1;
-// }
buf[0] = s->modifiers & 0xff;
buf[1] = 0;
{
USBHIDState *s = (USBHIDState *)dev;
- qemu_add_kbd_event_handler(usb_keyboard_event, s, "USB Keyboard");
+ qemu_add_kbd_event_handler(usb_keyboard_event, s);
memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes));
s->head = 0;
s->n = 0;
switch(s->kind) {
case USB_KEYBOARD:
- qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ qemu_remove_kbd_event_handler();
break;
default:
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
starting_frame = OHCI_BM(iso_td.flags, TD_SF);
frame_count = OHCI_BM(iso_td.flags, TD_FC);
- relative_frame_number = USUB(ohci->frame_number, starting_frame);
+ relative_frame_number = USUB(ohci->frame_number, starting_frame);
#ifdef DEBUG_ISOCH
printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
- ohci->frame_number, starting_frame,
- frame_count, relative_frame_number,
+ ohci->frame_number, starting_frame,
+ frame_count, relative_frame_number,
OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
#endif
} else if (relative_frame_number > frame_count) {
/* ISO TD expired - retire the TD to the Done Queue and continue with
the next ISO TD of the same ED */
- DPRINTF("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number,
+ DPRINTF("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number,
frame_count);
OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
ed->head &= ~OHCI_DPTR_MASK;
start_offset = iso_td.offset[relative_frame_number];
next_offset = iso_td.offset[relative_frame_number + 1];
- if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) ||
- ((relative_frame_number < frame_count) &&
+ if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) ||
+ ((relative_frame_number < frame_count) &&
!(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
start_offset, next_offset);
if (ret != USB_RET_NODEV)
break;
}
-
+
if (ret == USB_RET_ASYNC) {
return 1;
}
.attach = ohci_attach,
.detach = ohci_detach,
};
-static void usb_ohci_save(QEMUFile *f, void *opaque)
-{
- USBPort *portl = (USBPort *)opaque;
- OHCIState *port_info;
- uint32_t port_state;
- int i;
-
- for (i = 0; i < OHCI_MAX_PORTS; i++) {
- port_info = portl[i].opaque;
- port_state = port_info->rhport[portl[i].index].ctrl;
- if (port_state & OHCI_PORT_CCS) {
- hw_error("usb-ohci: some device is attached to usb-port. "
- "SaveVM is not possible\n");
- }
- }
-}
-
-static int usb_ohci_load(QEMUFile *f, void *opaque, int version_id)
-{
- if (version_id != 1)
- return -EINVAL;
-
- return 0;
-}
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
int num_ports, uint32_t localmem_base)
ohci->async_td = 0;
qemu_register_reset(ohci_reset, ohci);
-
- register_savevm(dev, "usb-ohci", -1, 1,
- usb_ohci_save, usb_ohci_load, ohci->rhport);
}
typedef struct {
int button_state; /* Last seen pointer button state */
int extended;
QEMUPutMouseEntry *qmouse;
- QEMUPutKbdEntry *qkbd;
};
#define UP_QUEUE 8
if (scancode == 0xe0) {
xenfb->extended = 1;
- return 0;
+ return;
} else if (scancode & 0x80) {
scancode &= 0x7f;
down = 0;
xenfb->extended = 0;
}
xenfb_send_key(xenfb, down, scancode2linux[scancode]);
- return 0;
}
/*
if (rc != 0)
return rc;
- in->qkbd = qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
+ qemu_add_kbd_event_handler(xenfb_key_event, in);
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_remove_kbd_event_handler(in->qkbd);
+ qemu_add_kbd_event_handler(NULL, NULL);
common_unbind(&in->c);
}
#include "console.h"
#include "qjson.h"
-static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers =
- QTAILQ_HEAD_INITIALIZER(kbd_handlers);
+static QEMUPutKBDEvent *qemu_put_kbd_event;
+static void *qemu_put_kbd_event_opaque;
+static QEMUPutKBDEvent *qemu_put_ps2kbd_event;
+static void *qemu_put_ps2kbd_event_opaque;
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
QTAILQ_HEAD_INITIALIZER(mouse_handlers);
static NotifierList mouse_mode_notifiers =
NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
+void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
+{
+ qemu_put_kbd_event_opaque = opaque;
+ qemu_put_kbd_event = func;
+}
+
+void qemu_remove_kbd_event_handler(void)
+{
+ qemu_put_kbd_event_opaque = NULL;
+ qemu_put_kbd_event = NULL;
+}
+
+void qemu_add_ps2kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
+{
+ qemu_add_kbd_event_handler(func,opaque); // temporary code for compatibility with Xserver
+ qemu_put_ps2kbd_event_opaque = opaque;
+ qemu_put_ps2kbd_event = func;
+}
+
+void qemu_remove_ps2kbd_event_handler(void)
+{
+ qemu_put_ps2kbd_event_opaque = NULL;
+ qemu_put_ps2kbd_event = NULL;
+}
+
static void check_mode_change(void)
{
static int current_is_absolute, current_has_absolute;
current_has_absolute = has_absolute;
}
-QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
- void *opaque,
- const char *name)
-{
- static int index = 0;
- QEMUPutKbdEntry *s, *cursor;
-
- QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
- if (cursor->qemu_put_kbd_event == func &&
- cursor->qemu_put_kbd_event_opaque == opaque) {
- return cursor;
- }
- }
-
- s = qemu_mallocz(sizeof(QEMUPutKbdEntry));
-
- s->qemu_put_kbd_event_opaque = opaque;
- s->qemu_put_kbd_event = func;
- s->qemu_put_kbd_name = qemu_strdup(name);
- s->index = index++;
-
- QTAILQ_INSERT_TAIL(&kbd_handlers, s, node);
-
- return s;
-}
-
-void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
-{
- QTAILQ_REMOVE(&kbd_handlers, entry, node);
- qemu_free(entry);
-}
-
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name)
void kbd_put_keycode(int keycode)
{
- QEMUPutKbdEntry *entry;
- QTAILQ_FOREACH(entry, &kbd_handlers, node) {
- if (!entry->qemu_put_kbd_event(entry->qemu_put_kbd_event_opaque,
- keycode)) {
- break;
- }
+ if (qemu_put_kbd_event) {
+ qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
+ }
+}
+
+void ps2kbd_put_keycode(int keycode)
+{
+ if (qemu_put_ps2kbd_event) {
+ qemu_put_ps2kbd_event(qemu_put_ps2kbd_event_opaque, keycode);
}
}
{
notifier_list_remove(&mouse_mode_notifiers, notify);
}
-
-static void info_keyboard_iter(QObject *data, void *opaque)
-{
- QDict *kbd;
- Monitor *mon = opaque;
-
- kbd = qobject_to_qdict(data);
- monitor_printf(mon, "%c Keyboard #%" PRId64 ": %s\n",
- (qdict_get_bool(kbd, "current") ? '*' : ' '),
- qdict_get_int(kbd, "index"), qdict_get_str(kbd, "name"));
-}
-
-void do_info_keyboard_print(Monitor *mon, const QObject *data)
-{
- QList *kbd_list;
-
- kbd_list = qobject_to_qlist(data);
- if (qlist_empty(kbd_list)) {
- monitor_printf(mon, "No keyboard devices connected\n");
- return;
- }
-
- qlist_iter(kbd_list, info_keyboard_iter, mon);
-}
-
-void qemu_activate_keyboard_event_handler(QEMUPutKbdEntry *entry)
-{
- QTAILQ_REMOVE(&kbd_handlers, entry, node);
- QTAILQ_INSERT_HEAD(&kbd_handlers, entry, node);
-}
-
-/*
- * do_info_keyboard(): Show VM keyboard information
- *
- * Each keyboard is represented by a QDict, the returned QObject is
- * a QList of all keyboards.
- *
- * The keyboard QDict contains the following:
- *
- * - "name": keyboard's name
- * - "index": keyboard's index
- * - "current": true if this keyboard is receiving events, false otherwise
- *
- * Example:
- *
- * [ { "name": "QEMU USB Keyboard", "index": 0, "current": false },
- * { "name": "QEMU PS/2 Keyboard", "index": 1, "current": true } ]
- */
-void do_info_keyboard(Monitor *mon, QObject **ret_data)
-{
- QEMUPutKbdEntry *cursor;
- QList *kbd_list;
- int current;
-
- kbd_list = qlist_new();
-
- if (QTAILQ_EMPTY(&kbd_handlers)) {
- goto out;
- }
-
- current = QTAILQ_FIRST(&kbd_handlers)->index;
- QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
- QObject *obj;
- obj = qobject_from_jsonf("{ 'name': %s,"
- " 'index': %d,"
- " 'current': %i }",
- cursor->qemu_put_kbd_name,
- cursor->index,
- current == cursor->index);
- qlist_append_obj(kbd_list, obj);
- }
-out:
- *ret_data = QOBJECT(kbd_list);
-}
-
-/*
- * do_keyboard_set(): Set active keyboard
- *
- * Argument qdict contains
- * - "index": the keyboard index to set
- *
- * Example:
- *
- * { "index": "0" }
- */
-int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
-{
- QEMUPutKbdEntry *cursor;
- int index = qdict_get_int(qdict, "index");
- int found = 0;
-
- if (QTAILQ_EMPTY(&kbd_handlers)) {
- qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
- return -1;
- }
-
- QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
- if (cursor->index == index) {
- qemu_activate_keyboard_event_handler(cursor);
- found = 1;
- break;
- }
- }
-
- if (!found) {
- qerror_report(QERR_INVALID_PARAMETER, "index");
- return -1;
- }
-
- return 0;
-}
#include "hw/hw.h"
#include "hw/qdev.h"
#include "hw/usb.h"
-#include "hw/usb-ehci.h"
#include "hw/pcmcia.h"
#include "hw/pc.h"
#include "hw/pci.h"
.mhandler.info_new = do_info_mice,
},
{
- .name = "keyboard",
- .args_type = "",
- .params = "",
- .help = "show which guest keyboard is receiving events",
- .user_print = do_info_keyboard_print,
- .mhandler.info_new = do_info_keyboard,
- },
- {
.name = "vnc",
.args_type = "",
.params = "",
@end table
ETEXI
-#ifdef CONFIG_GLES2
-STEXI
-@table @option
-ETEXI
-DEF("gles2-quality", HAS_ARG, QEMU_OPTION_gles2_quality,
- "-gles2-quality set GLES 2.0 rendering quality [0 ... 100]\n",
- QEMU_ARCH_ARM)
-STEXI
-@end table
-ETEXI
-#endif
-
DEFHEADING(Network options:)
STEXI
@table @option
Linux*)
echo "checking for os... targetos $targetos"
exec ./configure \
- --target-list=i386-softmmu,arm-softmmu \
+ --target-list=i386-softmmu \
--disable-werror \
--audio-drv-list=pa \
--enable-mixemu \
EQMP
{
- .name = "mouse_move",
- .args_type = "dx_str:s,dy_str:s,dz_str:s?",
- .params = "dx dy [dz]",
- .help = "send mouse move events",
- .mhandler.cmd = do_mouse_move,
- },
-
-STEXI
-@item mouse_move @var{dx} @var{dy} [@var{dz}]
-@findex mouse_move
-Move the active mouse to the specified coordinates @var{dx} @var{dy}
-with optional scroll axis @var{dz}.
-ETEXI
-
- {
- .name = "mouse_button",
- .args_type = "button_state:i",
- .params = "state",
- .help = "change mouse button state (1=L, 2=M, 4=R)",
- .mhandler.cmd = do_mouse_button,
- },
-
-STEXI
-@item mouse_button @var{val}
-@findex mouse_button
-Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
-ETEXI
-
- {
- .name = "mouse_set",
- .args_type = "index:i",
- .params = "index",
- .help = "set which mouse device receives events",
- .mhandler.cmd = do_mouse_set,
- },
-
-STEXI
-@item mouse_set @var{index}
-@findex mouse_set
-Set which mouse device receives events at given @var{index}, index
-can be obtained with
-@example
-info mice
-@end example
-ETEXI
-
- {
- .name = "keyboard_set",
- .args_type = "index:i",
- .params = "index",
- .help = "set which keyboard device receives events",
- .mhandler.cmd_new = do_keyboard_set,
- },
-
-STEXI
-@item keyboard_set @var{index}
-@findex keyboard_set
-Set which keyboard device receives events at given @var{index}, index
-can be obtained with
-@example
-info keyboard
-@end example
-ETEXI
-
-#ifdef HAS_AUDIO
- {
- .name = "wavcapture",
- .args_type = "path:F,freq:i?,bits:i?,nchannels:i?",
- .params = "path [frequency [bits [channels]]]",
- .help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
- .mhandler.cmd = do_wav_capture,
- },
-#endif
-STEXI
-@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
-@findex wavcapture
-Capture audio into @var{filename}. Using sample rate @var{frequency}
-bits per sample @var{bits} and number of channels @var{channels}.
-
-Defaults:
-@itemize @minus
-@item Sample rate = 44100 Hz - CD quality
-@item Bits = 16
-@item Number of channels = 2 - Stereo
-@end itemize
-ETEXI
-
-#ifdef HAS_AUDIO
- {
- .name = "stopcapture",
- .args_type = "n:i",
- .params = "capture index",
- .help = "stop capture",
- .mhandler.cmd = do_stop_capture,
- },
-#endif
-STEXI
-@item stopcapture @var{index}
-@findex stopcapture
-Stop capture with a given @var{index}, index can be obtained with
-@example
-info capture
-@end example
-ETEXI
-
- {
.name = "memsave",
.args_type = "val:l,size:i,filename:s",
.params = "addr size file",
const char *message);
void icmp_reflect(struct mbuf *);
-#ifndef _WIN32
-#include <sys/wait.h>
-#endif
-#include <unistd.h>
-
#endif
#define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */
#define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */
#define EXCP_STREX 10
-#define EXCP_SMC 11 /* secure monitor call */
#define ARMV7M_EXCP_RESET 1
#define ARMV7M_EXCP_NMI 2
uint32_t spsr;
/* Banked registers. */
- uint32_t banked_spsr[7];
- uint32_t banked_r13[7];
- uint32_t banked_r14[7];
+ uint32_t banked_spsr[6];
+ uint32_t banked_r13[6];
+ uint32_t banked_r14[6];
/* These hold r8-r12. */
uint32_t usr_regs[5];
uint32_t GE; /* cpsr[19:16] */
uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
- uint32_t actual_condexec_bits; /* Real IT bits updated as execution goes. */
- uint32_t saved_condexec_bits; /* Saved IT bits to be restored after interrupt. */
- uint32_t saved_condexec_tb; /* Address of a new TB after interrupt inside of IT block. */
/* System control coprocessor (cp15) */
struct {
uint32_t c1_sys; /* System control register. */
uint32_t c1_coproc; /* Coprocessor access register. */
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
- uint32_t c1_secfg; /* Secure configuration register. */
- uint32_t c1_sedbg; /* Secure debug enable register. */
- uint32_t c1_nseac; /* Non-secure access control register. */
uint32_t c2_base0; /* MMU translation table base 0. */
uint32_t c2_base1; /* MMU translation table base 1. */
uint32_t c2_control; /* MMU translation table base control. */
uint32_t c6_data;
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
- uint32_t c12_vbar; /* secure/nonsecure vector base address register. */
- uint32_t c12_mvbar; /* monitor vector base address register. */
uint32_t c13_fcse; /* FCSE PID. */
uint32_t c13_context; /* Context ID. */
uint32_t c13_tls1; /* User RW Thread register. */
if (mask & CPSR_IT_0_1) {
env->condexec_bits &= ~3;
env->condexec_bits |= (val >> 25) & 3;
- env->actual_condexec_bits = env->condexec_bits;
}
if (mask & CPSR_IT_2_7) {
env->condexec_bits &= 3;
env->condexec_bits |= (val >> 8) & 0xfc;
- env->actual_condexec_bits = env->condexec_bits;
}
if (mask & 0x1ff) {
env->v7m.exception = val & 0x1ff;
ARM_CPU_MODE_FIQ = 0x11,
ARM_CPU_MODE_IRQ = 0x12,
ARM_CPU_MODE_SVC = 0x13,
- ARM_CPU_MODE_SMC = 0x16,
ARM_CPU_MODE_ABT = 0x17,
ARM_CPU_MODE_UND = 0x1b,
ARM_CPU_MODE_SYS = 0x1f
ARM_FEATURE_DIV,
ARM_FEATURE_M, /* Microcontroller profile. */
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
- ARM_FEATURE_THUMB2EE,
- ARM_FEATURE_TRUSTZONE /* TrustZone Security Extensions. */
+ ARM_FEATURE_THUMB2EE
};
static inline int arm_feature(CPUARMState *env, int feature)
#define ARM_CPUID_ARM1136_R2 0x4107b362
#define ARM_CPUID_ARM11MPCORE 0x410fb022
#define ARM_CPUID_CORTEXA8 0x410fc080
-#define ARM_CPUID_CORTEXA8_R2 0x412fc083
#define ARM_CPUID_CORTEXA9 0x410fc090
#define ARM_CPUID_CORTEXM3 0x410fc231
#define ARM_CPUID_ANY 0xffffffff
static uint32_t cortexa8_cp15_c0_c2[8] =
{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
-static uint32_t cortexa8r2_cp15_c0_c2[8] =
-{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00011142, 0, 0, 0 };
-
static uint32_t mpcore_cp15_c0_c1[8] =
{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
set_feature(env, ARM_FEATURE_VFP3);
set_feature(env, ARM_FEATURE_NEON);
set_feature(env, ARM_FEATURE_THUMB2EE);
- set_feature(env, ARM_FEATURE_TRUSTZONE);
env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */
env->cp15.c1_sys = 0x00c50078;
break;
- case ARM_CPUID_CORTEXA8_R2:
- set_feature(env, ARM_FEATURE_V6);
- set_feature(env, ARM_FEATURE_V6K);
- set_feature(env, ARM_FEATURE_V7);
- set_feature(env, ARM_FEATURE_AUXCR);
- set_feature(env, ARM_FEATURE_THUMB2);
- set_feature(env, ARM_FEATURE_VFP);
- set_feature(env, ARM_FEATURE_VFP3);
- set_feature(env, ARM_FEATURE_NEON);
- set_feature(env, ARM_FEATURE_THUMB2EE);
- set_feature(env, ARM_FEATURE_TRUSTZONE);
- env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c2;
- env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
- env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011111;
- memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
- memcpy(env->cp15.c0_c2, cortexa8r2_cp15_c0_c2, 8 * sizeof(uint32_t));
- env->cp15.c0_cachetype = 0x82048004;
- env->cp15.c0_clid = (1 << 27) | (2 << 24) | (4 << 3) | 3;
- env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */
- env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */
- env->cp15.c0_ccsid[2] = 0xf03fe03a; /* 256k L2 cache. */
- break;
case ARM_CPUID_CORTEXA9:
set_feature(env, ARM_FEATURE_V6);
set_feature(env, ARM_FEATURE_V6K);
set_feature(env, ARM_FEATURE_VFP_FP16);
set_feature(env, ARM_FEATURE_NEON);
set_feature(env, ARM_FEATURE_THUMB2EE);
- set_feature(env, ARM_FEATURE_TRUSTZONE);
env->vfp.xregs[ARM_VFP_FPSID] = 0x41034000; /* Guess */
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111;
{ ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
{ ARM_CPUID_CORTEXM3, "cortex-m3"},
{ ARM_CPUID_CORTEXA8, "cortex-a8"},
- { ARM_CPUID_CORTEXA8_R2, "cortex-a8-r2"},
{ ARM_CPUID_CORTEXA9, "cortex-a9"},
{ ARM_CPUID_TI925T, "ti925t" },
{ ARM_CPUID_PXA250, "pxa250" },
if (mask & CPSR_IT_0_1) {
env->condexec_bits &= ~3;
env->condexec_bits |= (val >> 25) & 3;
- env->actual_condexec_bits = env->condexec_bits;
}
if (mask & CPSR_IT_2_7) {
env->condexec_bits &= 3;
env->condexec_bits |= (val >> 8) & 0xfc;
- env->actual_condexec_bits = env->condexec_bits;
}
if (mask & CPSR_GE) {
env->GE = (val >> 16) & 0xf;
return 4;
case ARM_CPU_MODE_FIQ:
return 5;
- case ARM_CPU_MODE_SMC:
- return 6;
}
cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
return -1;
int new_mode;
uint32_t offset;
-#if 0
- static uint32_t interrupt_count = 0;
- interrupt_count++;
- if ((interrupt_count % 4096) == 0)
- printf(" $$$ INTERRUPT COUNT = %u $$$ \n", interrupt_count);
-#endif
-
if (IS_M(env)) {
do_interrupt_v7m(env);
return;
mask = CPSR_A | CPSR_I | CPSR_F;
offset = 4;
break;
- case EXCP_SMC:
- if (semihosting_enabled) {
- cpu_abort(env, "SMC handling under semihosting not implemented\n");
- return;
- }
- if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SMC) {
- env->cp15.c1_secfg &= ~1;
- }
- offset = env->thumb ? 2 : 0;
- new_mode = ARM_CPU_MODE_SMC;
- addr = 0x08;
- mask = CPSR_A | CPSR_I | CPSR_F;
- break;
default:
cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
return; /* Never happens. Keep compiler happy. */
}
- /* Save actual IT bits along with the address where they belong.
- * When return from ISR happens these should be restored to preserve
- * correct execution. */
- if (env->thumb && env->actual_condexec_bits) {
- env->saved_condexec_tb = env->regs[15];
- env->saved_condexec_bits = env->actual_condexec_bits;
- env->actual_condexec_bits = 0;
- }
- if (arm_feature(env, ARM_FEATURE_TRUSTZONE)) {
- if (new_mode == ARM_CPU_MODE_SMC ||
- (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SMC) {
- addr += env->cp15.c12_mvbar;
- } else {
- if (env->cp15.c1_sys & (1 << 13)) {
- addr += 0xffff0000;
- } else {
- addr += env->cp15.c12_vbar;
- }
- }
- } else {
- /* High vectors. */
- if (env->cp15.c1_sys & (1 << 13)) {
- addr += 0xffff0000;
- }
+ /* High vectors. */
+ if (env->cp15.c1_sys & (1 << 13)) {
+ addr += 0xffff0000;
}
switch_mode (env, new_mode);
env->spsr = cpsr_read(env);
table = get_level1_table_address(env, address);
desc = ldl_phys(table);
type = (desc & 3);
- if (type == 0 || type == 3) {
+ if (type == 0) {
/* Section translation fault. */
code = 5;
domain = 0;
return 0;
}
-#ifdef CONFIG_GLES2
-int get_phys_addr(CPUState *env, uint32_t address,
- int access_type, int is_user,
- uint32_t *phys_ptr, int *prot,
- target_ulong *page_size);
-#else
-static inline
-#endif
-int get_phys_addr(CPUState *env, uint32_t address,
- int access_type, int is_user,
- uint32_t *phys_ptr, int *prot,
- target_ulong *page_size)
+static inline int get_phys_addr(CPUState *env, uint32_t address,
+ int access_type, int is_user,
+ uint32_t *phys_ptr, int *prot,
+ target_ulong *page_size)
{
/* Fast Context Switch Extension. */
if (address < 0x02000000)
}
goto bad_reg;
case 1: /* System configuration. */
- switch (crm) {
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
+ switch (op2) {
case 0:
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- if (!arm_feature(env, ARM_FEATURE_XSCALE))
- env->cp15.c1_sys = val;
- /* ??? Lots of these bits are not implemented. */
- /* This may enable/disable the MMU, so do a TLB flush. */
- tlb_flush(env, 1);
- break;
- case 1: /* Auxiliary cotrol register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- env->cp15.c1_xscaleauxcr = val;
- break;
- }
- /* Not implemented. */
- break;
- case 2:
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- if (env->cp15.c1_coproc != val) {
- env->cp15.c1_coproc = val;
- /* ??? Is this safe when called from within a TB? */
- tb_flush(env);
- }
+ if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
+ env->cp15.c1_sys = val;
+ /* ??? Lots of these bits are not implemented. */
+ /* This may enable/disable the MMU, so do a TLB flush. */
+ tlb_flush(env, 1);
+ break;
+ case 1: /* Auxiliary cotrol register. */
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
+ env->cp15.c1_xscaleauxcr = val;
break;
- default:
- goto bad_reg;
}
+ /* Not implemented. */
break;
- case 1:
- if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
- || (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
- goto bad_reg;
- switch (op2) {
- case 0: /* Secure configuration register. */
- if (env->cp15.c1_secfg & 1)
- goto bad_reg;
- env->cp15.c1_secfg = val;
- break;
- case 1: /* Secure debug enable register. */
- if (env->cp15.c1_secfg & 1)
- goto bad_reg;
- env->cp15.c1_sedbg = val;
- break;
- case 2: /* Nonsecure access control register. */
- if (env->cp15.c1_secfg & 1)
- goto bad_reg;
- env->cp15.c1_nseac = val;
- break;
- default:
+ case 2:
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
goto bad_reg;
+ if (env->cp15.c1_coproc != val) {
+ env->cp15.c1_coproc = val;
+ /* ??? Is this safe when called from within a TB? */
+ tb_flush(env);
}
break;
default:
goto bad_reg;
}
} else {
- switch (op2) {
- case 0:
- env->cp15.c2_base0 = val;
- break;
- case 1:
- env->cp15.c2_base1 = val;
- break;
- case 2:
+ switch (op2) {
+ case 0:
+ env->cp15.c2_base0 = val;
+ break;
+ case 1:
+ env->cp15.c2_base1 = val;
+ break;
+ case 2:
val &= 7;
env->cp15.c2_control = val;
- env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
+ env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
- break;
- default:
- goto bad_reg;
- }
+ break;
+ default:
+ goto bad_reg;
+ }
}
break;
case 3: /* MMU Domain access control / MPU write buffer control. */
break;
switch (crm) {
case 0: /* Cache lockdown. */
- switch (op1) {
- case 0: /* L1 cache. */
- switch (op2) {
- case 0:
- env->cp15.c9_data = val;
- break;
- case 1:
- env->cp15.c9_insn = val;
- break;
- default:
- goto bad_reg;
- }
- break;
- case 1: /* L2 cache. */
- /* Ignore writes to L2 lockdown/auxiliary registers. */
- break;
- default:
- goto bad_reg;
- }
- break;
+ switch (op1) {
+ case 0: /* L1 cache. */
+ switch (op2) {
+ case 0:
+ env->cp15.c9_data = val;
+ break;
+ case 1:
+ env->cp15.c9_insn = val;
+ break;
+ default:
+ goto bad_reg;
+ }
+ break;
+ case 1: /* L2 cache. */
+ /* Ignore writes to L2 lockdown/auxiliary registers. */
+ break;
+ default:
+ goto bad_reg;
+ }
+ break;
case 1: /* TCM memory region registers. */
/* Not implemented. */
goto bad_reg;
- case 12: /* Performance counters. */
- break;
default:
goto bad_reg;
}
/* ??? TLB lockdown not implemented. */
break;
case 12: /* Reserved. */
- if (!op1 && !crm) {
- switch (op2) {
- case 0:
- if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)) {
- goto bad_reg;
- }
- env->cp15.c12_vbar = val & ~0x1f;
- break;
- case 1:
- if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)) {
- goto bad_reg;
- }
- if (!(env->cp15.c1_secfg & 1)) {
- env->cp15.c12_mvbar = val & ~0x1f;
- }
- break;
- default:
- goto bad_reg;
- }
- break;
- }
goto bad_reg;
case 13: /* Process ID. */
switch (op2) {
case 0: /* Device ID. */
return env->cp15.c0_cpuid;
case 1: /* Cache Type. */
- return env->cp15.c0_cachetype;
+ return env->cp15.c0_cachetype;
case 2: /* TCM status. */
return 0;
case 3: /* TLB type register. */
default:
goto bad_reg;
}
- break;
case 1:
/* These registers aren't documented on arm11 cores. However
Linux looks at them anyway. */
default:
goto bad_reg;
}
- break;
case 1: /* System configuration. */
- switch (crm) {
- case 0:
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0: /* Control register. */
- return env->cp15.c1_sys;
- case 1: /* Auxiliary control register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- return env->cp15.c1_xscaleauxcr;
- if (!arm_feature(env, ARM_FEATURE_AUXCR))
- goto bad_reg;
- switch (ARM_CPUID(env)) {
- case ARM_CPUID_ARM1026:
- return 1;
- case ARM_CPUID_ARM1136:
- case ARM_CPUID_ARM1136_R2:
- return 7;
- case ARM_CPUID_ARM11MPCORE:
- return 1;
- case ARM_CPUID_CORTEXA8:
- case ARM_CPUID_CORTEXA8_R2:
- return 2;
- case ARM_CPUID_CORTEXA9:
- return 0;
- default:
- goto bad_reg;
- }
- break;
- case 2: /* Coprocessor access register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- return env->cp15.c1_coproc;
- default:
- goto bad_reg;
- }
- break;
- case 1:
- if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
- || (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
+ switch (op2) {
+ case 0: /* Control register. */
+ return env->cp15.c1_sys;
+ case 1: /* Auxiliary control register. */
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
+ return env->cp15.c1_xscaleauxcr;
+ if (!arm_feature(env, ARM_FEATURE_AUXCR))
goto bad_reg;
- switch (op2) {
- case 0: /* Secure configuration register. */
- if (env->cp15.c1_secfg & 1)
- goto bad_reg;
- return env->cp15.c1_secfg;
- case 1: /* Secure debug enable register. */
- if (env->cp15.c1_secfg & 1)
- goto bad_reg;
- return env->cp15.c1_sedbg;
- case 2: /* Nonsecure access control register. */
- return env->cp15.c1_nseac;
+ switch (ARM_CPUID(env)) {
+ case ARM_CPUID_ARM1026:
+ return 1;
+ case ARM_CPUID_ARM1136:
+ case ARM_CPUID_ARM1136_R2:
+ return 7;
+ case ARM_CPUID_ARM11MPCORE:
+ return 1;
+ case ARM_CPUID_CORTEXA8:
+ return 2;
+ case ARM_CPUID_CORTEXA9:
+ return 0;
default:
goto bad_reg;
}
- break;
+ case 2: /* Coprocessor access register. */
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
+ goto bad_reg;
+ return env->cp15.c1_coproc;
default:
goto bad_reg;
}
- break;
case 2: /* MMU Page table control / MPU cache control. */
if (arm_feature(env, ARM_FEATURE_MPU)) {
switch (op2) {
goto bad_reg;
}
} else {
- switch (op2) {
- case 0:
- return env->cp15.c2_base0;
- case 1:
- return env->cp15.c2_base1;
- case 2:
+ switch (op2) {
+ case 0:
+ return env->cp15.c2_base0;
+ case 1:
+ return env->cp15.c2_base1;
+ case 2:
return env->cp15.c2_control;
- default:
- goto bad_reg;
- }
- }
+ default:
+ goto bad_reg;
+ }
+ }
case 3: /* MMU Domain access control / MPU write buffer control. */
return env->cp15.c3;
case 4: /* Reserved. */
} else {
if (arm_feature(env, ARM_FEATURE_OMAPCP))
op2 = 0;
- switch (op2) {
- case 0:
- return env->cp15.c6_data;
- case 1:
- if (arm_feature(env, ARM_FEATURE_V6)) {
- /* Watchpoint Fault Adrress. */
- return 0; /* Not implemented. */
- }
- /* Instruction Fault Adrress. */
- /* Arm9 doesn't have an IFAR, but implementing it anyway
- shouldn't do any harm. */
- return env->cp15.c6_insn;
- case 2:
- if (arm_feature(env, ARM_FEATURE_V6)) {
- /* Instruction Fault Adrress. */
- return env->cp15.c6_insn;
- }
- goto bad_reg;
- default:
- goto bad_reg;
- }
+ switch (op2) {
+ case 0:
+ return env->cp15.c6_data;
+ case 1:
+ if (arm_feature(env, ARM_FEATURE_V6)) {
+ /* Watchpoint Fault Adrress. */
+ return 0; /* Not implemented. */
+ } else {
+ /* Instruction Fault Adrress. */
+ /* Arm9 doesn't have an IFAR, but implementing it anyway
+ shouldn't do any harm. */
+ return env->cp15.c6_insn;
+ }
+ case 2:
+ if (arm_feature(env, ARM_FEATURE_V6)) {
+ /* Instruction Fault Adrress. */
+ return env->cp15.c6_insn;
+ } else {
+ goto bad_reg;
+ }
+ default:
+ goto bad_reg;
+ }
}
case 7: /* Cache control. */
- if (((insn >> 12) & 0xf) == 0xf) /* clear ZF only if destination is r15 */
- env->ZF = 0;
+ /* FIXME: Should only clear Z flag if destination is r15. */
+ env->ZF = 0;
return 0;
case 8: /* MMU TLB control. */
goto bad_reg;
case 9: /* Cache lockdown. */
switch (op1) {
case 0: /* L1 cache. */
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- return 0;
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ return 0;
switch (op2) {
case 0:
return env->cp15.c9_data;
return 0;
case 11: /* TCM DMA control. */
case 12: /* Reserved. */
- if (!op1 && !crm) {
- switch (op2) {
- case 0: /* secure or nonsecure vector base address */
- if (arm_feature(env, ARM_FEATURE_TRUSTZONE)) {
- return env->cp15.c12_vbar;
- }
- break;
- case 1: /* monitor vector base address */
- if (arm_feature(env, ARM_FEATURE_TRUSTZONE)) {
- return env->cp15.c12_mvbar;
- }
- break;
- default:
- break;
- }
- }
goto bad_reg;
case 13: /* Process ID. */
switch (op2) {
DEF_HELPER_2(recpe_u32, i32, i32, env)
DEF_HELPER_2(rsqrte_u32, i32, i32, env)
DEF_HELPER_4(neon_tbl, i32, i32, i32, i32, i32)
-DEF_HELPER_2(neon_add_saturate_u64, i64, i64, i64)
-DEF_HELPER_2(neon_add_saturate_s64, i64, i64, i64)
-DEF_HELPER_2(neon_sub_saturate_u64, i64, i64, i64)
-DEF_HELPER_2(neon_sub_saturate_s64, i64, i64, i64)
-
DEF_HELPER_2(add_cc, i32, i32, i32)
DEF_HELPER_2(adc_cc, i32, i32, i32)
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
DEF_HELPER_2(neon_mul_p8, i32, i32, i32)
-DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
DEF_HELPER_1(neon_narrow_u8, i32, i64)
DEF_HELPER_1(neon_narrow_u16, i32, i64)
-DEF_HELPER_2(neon_unarrow_sat8, i32, env, i64)
DEF_HELPER_2(neon_narrow_sat_u8, i32, env, i64)
DEF_HELPER_2(neon_narrow_sat_s8, i32, env, i64)
-DEF_HELPER_2(neon_unarrow_sat16, i32, env, i64)
DEF_HELPER_2(neon_narrow_sat_u16, i32, env, i64)
DEF_HELPER_2(neon_narrow_sat_s16, i32, env, i64)
-DEF_HELPER_2(neon_unarrow_sat32, i32, env, i64)
DEF_HELPER_2(neon_narrow_sat_u32, i32, env, i64)
DEF_HELPER_2(neon_narrow_sat_s32, i32, env, i64)
DEF_HELPER_1(neon_narrow_high_u8, i32, i64)
DEF_HELPER_2(set_teecr, void, env, i32)
-DEF_HELPER_2(neon_unzip, void, env, i32)
-DEF_HELPER_2(neon_zip, void, env, i32)
-DEF_HELPER_2(neon_vldst_all, void, env, i32)
-
#include "def-helper.h"
qemu_put_be32(f, env->cp15.c1_sys);
qemu_put_be32(f, env->cp15.c1_coproc);
qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
- qemu_put_be32(f, env->cp15.c1_secfg);
- qemu_put_be32(f, env->cp15.c1_sedbg);
- qemu_put_be32(f, env->cp15.c1_nseac);
qemu_put_be32(f, env->cp15.c2_base0);
qemu_put_be32(f, env->cp15.c2_base1);
qemu_put_be32(f, env->cp15.c2_control);
env->cp15.c1_sys = qemu_get_be32(f);
env->cp15.c1_coproc = qemu_get_be32(f);
env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
- env->cp15.c1_secfg = qemu_get_be32(f);
- env->cp15.c1_sedbg = qemu_get_be32(f);
- env->cp15.c1_nseac = qemu_get_be32(f);
env->cp15.c2_base0 = qemu_get_be32(f);
env->cp15.c2_base1 = qemu_get_be32(f);
env->cp15.c2_control = qemu_get_be32(f);
float32 s;
} v;
- /* flush-to-zero */
- if (!(i & (0xff << 23))) {
- i &= 1 << 31; /* make it +-0 */
- }
-
v.i = i;
return v.s;
}
}} while (0)
NEON_VOP(rshl_s8, neon_s8, 4)
NEON_VOP(rshl_s16, neon_s16, 2)
+NEON_VOP(rshl_s32, neon_s32, 1)
#undef NEON_FN
-uint32_t HELPER(neon_rshl_s32)(uint32_t valop, uint32_t shiftop)
-{
- int8_t shift =(int8_t)shiftop;
- int32_t val = valop;
- if (shift >= 32) {
- val = 0;
- } else if (shift < -32) {
- val >>= 31;
- } else if (shift == -32) {
- val >>= 31;
- val++;
- val >>= 1;
- } else if (shift < 0) {
- val = ((int64_t)val + (1 << (-1 - shift))) >> -shift;
- } else {
- val <<= shift;
- }
- return val;
-}
-
uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
{
int8_t shift = (int8_t)shiftop;
val = 0;
} else if (shift < -64) {
val >>= 63;
- } else if (shift == -64) {
+ } else if (shift == -63) {
val >>= 63;
val++;
val >>= 1;
tmp < -(ssize_t)sizeof(src1) * 8) { \
dest = 0; \
} else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
- dest = src1 >> (-tmp - 1); \
+ dest = src1 >> (tmp - 1); \
} else if (tmp < 0) { \
dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
} else { \
}} while (0)
NEON_VOP(rshl_u8, neon_u8, 4)
NEON_VOP(rshl_u16, neon_u16, 2)
+NEON_VOP(rshl_u32, neon_u32, 1)
#undef NEON_FN
-uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- if (shift >= 32 || shift < -32) {
- val = 0;
- } else if (shift == -32) {
- val >>= 31;
- } else if (shift < 0) {
- val = ((uint64_t)val + (1 << (-1 - shift))) >> -shift;
- } else {
- val <<= shift;
- }
- return val;
-}
-
uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
{
int8_t shift = (uint8_t)shiftop;
- if (shift >= 64 || shift < -64) {
+ if (shift >= 64 || shift < 64) {
val = 0;
} else if (shift == -64) {
/* Rounding a 1-bit result just preserves that bit. */
val >>= 63;
} if (shift < 0) {
- uint64_t r = ((uint64_t)1 << (-1 - shift));
- uint64_t lo = val + r;
- if (lo < val || lo < r) {
- val = (lo >> -shift) | ((1ull << 63) >> (-shift - 1));
- } else {
- val = lo >> -shift;
- }
+ val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift;
+ val >>= -shift;
} else {
val <<= shift;
}
}} while (0)
NEON_VOP_ENV(qrshl_u8, neon_u8, 4)
NEON_VOP_ENV(qrshl_u16, neon_u16, 2)
+NEON_VOP_ENV(qrshl_u32, neon_u32, 1)
#undef NEON_FN
-uint32_t HELPER(neon_qrshl_u32)(CPUState *env, uint32_t val, uint32_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- if (shift < 0) {
- val = ((uint64_t)val + (1 << (-1 - shift))) >> -shift;
- } else {
- uint32_t tmp = val;
- val <<= shift;
- if ((val >> shift) != tmp) {
- SET_QC();
- val = ~0;
- }
- }
- return val;
-}
-
uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
{
int8_t shift = (int8_t)shiftop;
dest = src1 << tmp; \
if ((dest >> tmp) != src1) { \
SET_QC(); \
- dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)) - (src1 > 0 ? 1 : 0); \
+ dest = src1 >> 31; \
} \
}} while (0)
NEON_VOP_ENV(qrshl_s8, neon_s8, 4)
if (shift < 0) {
val = (val + (1 << (-1 - shift))) >> -shift;
} else {
- int64_t tmp = val;
+ int64_t tmp = val;;
val <<= shift;
if ((val >> shift) != tmp) {
SET_QC();
return result;
}
-uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
-{
- int i;
- uint64_t result = 0;
- uint8_t e1;
- uint16_t e2, r;
-#define MULP8(n) \
- e1 = (op1 >> n) & 0xff; \
- e2 = (op2 >> n) & 0xff; \
- for (i = 0, r = 0; e1; i++, e1 >>= 1) { \
- if (e1 & 1) { \
- r ^= e2 << i; \
- } \
- } \
- result |= (uint64_t)r << (n * 2);
-
- MULP8(0);
- MULP8(8);
- MULP8(16);
- MULP8(24);
-#undef MULP8
- return result;
-}
-
#define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
NEON_VOP(tst_u8, neon_u8, 4)
NEON_VOP(tst_u16, neon_u16, 2)
return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
}
-uint32_t HELPER(neon_unarrow_sat8)(CPUState *env, uint64_t x)
-{
- uint16_t s;
- uint8_t d;
- uint32_t res = 0;
-#define SAT8(n) \
- s = x >> n; \
- if (s & 0x8000) { \
- SET_QC(); \
- } else { \
- if (s > 0xff) { \
- d = 0xff; \
- SET_QC(); \
- } else { \
- d = s; \
- } \
- res |= (uint32_t)d << (n / 2); \
- }
-
- SAT8(0);
- SAT8(16);
- SAT8(32);
- SAT8(48);
-#undef SAT8
- return res;
-}
-
uint32_t HELPER(neon_narrow_sat_u8)(CPUState *env, uint64_t x)
{
uint16_t s;
return res;
}
-uint32_t HELPER(neon_unarrow_sat16)(CPUState *env, uint64_t x)
-{
- uint32_t high;
- uint32_t low;
- low = x;
- if (low & 0x80000000) {
- low = 0;
- SET_QC();
- } else if (low > 0xffff) {
- low = 0xffff;
- SET_QC();
- }
- high = x >> 32;
- if (high & 0x80000000) {
- high = 0;
- SET_QC();
- } else if (high > 0xffff) {
- high = 0xffff;
- SET_QC();
- }
- return low | (high << 16);
-}
-
uint32_t HELPER(neon_narrow_sat_u16)(CPUState *env, uint64_t x)
{
uint32_t high;
return (uint16_t)low | (high << 16);
}
-uint32_t HELPER(neon_unarrow_sat32)(CPUState *env, uint64_t x)
-{
- if (x & 0x8000000000000000ull) {
- SET_QC();
- return 0;
- }
- if (x > 0xffffffffu) {
- SET_QC();
- return 0xffffffffu;
- }
- return x;
-}
-
uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x)
{
if (x > 0xffffffffu) {
uint32_t HELPER(neon_narrow_sat_s32)(CPUState *env, uint64_t x)
{
- if ((int64_t)x < -2147483648ll) {
- SET_QC();
- return 0x80000000;
- }
- if ((int64_t)x > 2147483647ll) {
+ if ((int64_t)x != (int32_t)x) {
SET_QC();
- return 0x7fffffff;
+ return (x >> 63) ^ 0x7fffffff;
}
return x;
}
return result;
}
+#include <stdio.h>
uint64_t HELPER(neon_negl_u32)(uint64_t x)
{
uint32_t low = -x;
float32 f1 = float32_abs(vfp_itos(b));
return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0;
}
-
-#define ELEM(V, N, SIZE) (uint64_t)(((uint64_t)(V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
-
-void HELPER(neon_unzip)(CPUState *env, uint32_t insn)
-{
- int rd = ((insn >> 18) & 0x10) | ((insn >> 12) & 0x0f);
- int rm = ((insn >> 1) & 0x10) | (insn & 0x0f);
- int size = (insn >> 18) & 3;
- if (insn & 0x40) { /* Q */
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
- uint64_t m0 = 0, m1 = 0, d0 = 0, d1 = 0;
- switch (size) {
- case 0:
- d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8)
- | (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24)
- | (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40)
- | (ELEM(zd1, 4, 8) << 48) | (ELEM(zd1, 6, 8) << 56);
- d1 = ELEM(zm0, 0, 8) | (ELEM(zm0, 2, 8) << 8)
- | (ELEM(zm0, 4, 8) << 16) | (ELEM(zm0, 6, 8) << 24)
- | (ELEM(zm1, 0, 8) << 32) | (ELEM(zm1, 2, 8) << 40)
- | (ELEM(zm1, 4, 8) << 48) | (ELEM(zm1, 6, 8) << 56);
- m0 = ELEM(zd0, 1, 8) | (ELEM(zd0, 3, 8) << 8)
- | (ELEM(zd0, 5, 8) << 16) | (ELEM(zd0, 7, 8) << 24)
- | (ELEM(zd1, 1, 8) << 32) | (ELEM(zd1, 3, 8) << 40)
- | (ELEM(zd1, 5, 8) << 48) | (ELEM(zd1, 7, 8) << 56);
- m1 = ELEM(zm0, 1, 8) | (ELEM(zm0, 3, 8) << 8)
- | (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24)
- | (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40)
- | (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
- break;
- case 1:
- d0 = ELEM(zd0, 0, 16) | (ELEM(zd0, 2, 16) << 16)
- | (ELEM(zd1, 0, 16) << 32) | (ELEM(zd1, 2, 16) << 48);
- d1 = ELEM(zm0, 0, 16) | (ELEM(zm0, 2, 16) << 16)
- | (ELEM(zm1, 0, 16) << 32) | (ELEM(zm1, 2, 16) << 48);
- m0 = ELEM(zd0, 1, 16) | (ELEM(zd0, 3, 16) << 16)
- | (ELEM(zd1, 1, 16) << 32) | (ELEM(zd1, 3, 16) << 48);
- m1 = ELEM(zm0, 1, 16) | (ELEM(zm0, 3, 16) << 16)
- | (ELEM(zm1, 1, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
- break;
- case 2:
- d0 = ELEM(zd0, 0, 32) | (ELEM(zd1, 0, 32) << 32);
- d1 = ELEM(zm0, 0, 32) | (ELEM(zm1, 0, 32) << 32);
- m0 = ELEM(zd0, 1, 32) | (ELEM(zd1, 1, 32) << 32);
- m1 = ELEM(zm0, 1, 32) | (ELEM(zm1, 1, 32) << 32);
- break;
- default:
- break;
- }
- env->vfp.regs[rm] = make_float64(m0);
- env->vfp.regs[rm + 1] = make_float64(m1);
- env->vfp.regs[rd] = make_float64(d0);
- env->vfp.regs[rd + 1] = make_float64(d1);
- } else {
- uint64_t zm = float64_val(env->vfp.regs[rm]);
- uint64_t zd = float64_val(env->vfp.regs[rd]);
- uint64_t m = 0, d = 0;
- switch (size) {
- case 0:
- d = ELEM(zd, 0, 8) | (ELEM(zd, 2, 8) << 8)
- | (ELEM(zd, 4, 8) << 16) | (ELEM(zd, 6, 8) << 24)
- | (ELEM(zm, 0, 8) << 32) | (ELEM(zm, 2, 8) << 40)
- | (ELEM(zm, 4, 8) << 48) | (ELEM(zm, 6, 8) << 56);
- m = ELEM(zd, 1, 8) | (ELEM(zd, 3, 8) << 8)
- | (ELEM(zd, 5, 8) << 16) | (ELEM(zd, 7, 8) << 24)
- | (ELEM(zm, 1, 8) << 32) | (ELEM(zm, 3, 8) << 40)
- | (ELEM(zm, 5, 8) << 48) | (ELEM(zm, 7, 8) << 56);
- break;
- case 1:
- d = ELEM(zd, 0, 16) | (ELEM(zd, 2, 16) << 16)
- | (ELEM(zm, 0, 16) << 32) | (ELEM(zm, 2, 16) << 48);
- m = ELEM(zd, 1, 16) | (ELEM(zd, 3, 16) << 16)
- | (ELEM(zm, 1, 16) << 32) | (ELEM(zm, 3, 16) << 48);
- break;
- default:
- /* size == 2 is a no-op for doubleword vectors */
- break;
- }
- env->vfp.regs[rm] = make_float64(m);
- env->vfp.regs[rd] = make_float64(d);
- }
-}
-
-void HELPER(neon_zip)(CPUState *env, uint32_t insn)
-{
- int rd = ((insn >> 18) & 0x10) | ((insn >> 12) & 0x0f);
- int rm = ((insn >> 1) & 0x10) | (insn & 0x0f);
- int size = (insn >> 18) & 3;
- if (insn & 0x40) { /* Q */
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
- uint64_t m0 = 0, m1 = 0, d0 = 0, d1 = 0;
- switch (size) {
- case 0:
- d0 = ELEM(zd0, 0, 8) | (ELEM(zm0, 0, 8) << 8)
- | (ELEM(zd0, 1, 8) << 16) | (ELEM(zm0, 1, 8) << 24)
- | (ELEM(zd0, 2, 8) << 32) | (ELEM(zm0, 2, 8) << 40)
- | (ELEM(zd0, 3, 8) << 48) | (ELEM(zm0, 3, 8) << 56);
- d1 = ELEM(zd0, 4, 8) | (ELEM(zm0, 4, 8) << 8)
- | (ELEM(zd0, 5, 8) << 16) | (ELEM(zm0, 5, 8) << 24)
- | (ELEM(zd0, 6, 8) << 32) | (ELEM(zm0, 6, 8) << 40)
- | (ELEM(zd0, 7, 8) << 48) | (ELEM(zm0, 7, 8) << 56);
- m0 = ELEM(zd1, 0, 8) | (ELEM(zm1, 0, 8) << 8)
- | (ELEM(zd1, 1, 8) << 16) | (ELEM(zm1, 1, 8) << 24)
- | (ELEM(zd1, 2, 8) << 32) | (ELEM(zm1, 2, 8) << 40)
- | (ELEM(zd1, 3, 8) << 48) | (ELEM(zm1, 3, 8) << 56);
- m1 = ELEM(zd1, 4, 8) | (ELEM(zm1, 4, 8) << 8)
- | (ELEM(zd1, 5, 8) << 16) | (ELEM(zm1, 5, 8) << 24)
- | (ELEM(zd1, 6, 8) << 32) | (ELEM(zm1, 6, 8) << 40)
- | (ELEM(zd1, 7, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
- break;
- case 1:
- d0 = ELEM(zd0, 0, 16) | (ELEM(zm0, 0, 16) << 16)
- | (ELEM(zd0, 1, 16) << 32) | (ELEM(zm0, 1, 16) << 48);
- d1 = ELEM(zd0, 2, 16) | (ELEM(zm0, 2, 16) << 16)
- | (ELEM(zd0, 3, 16) << 32) | (ELEM(zm0, 3, 16) << 48);
- m0 = ELEM(zd1, 0, 16) | (ELEM(zm1, 0, 16) << 16)
- | (ELEM(zd1, 1, 16) << 32) | (ELEM(zm1, 1, 16) << 48);
- m1 = ELEM(zd1, 2, 16) | (ELEM(zm1, 2, 16) << 16)
- | (ELEM(zd1, 3, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
- break;
- case 2:
- d0 = ELEM(zd0, 0, 32) | (ELEM(zm0, 0, 32) << 32);
- d1 = ELEM(zd0, 1, 32) | (ELEM(zm0, 1, 32) << 32);
- m0 = ELEM(zd1, 0, 32) | (ELEM(zm1, 0, 32) << 32);
- m1 = ELEM(zd1, 1, 32) | (ELEM(zm1, 1, 32) << 32);
- break;
- }
- env->vfp.regs[rm] = make_float64(m0);
- env->vfp.regs[rm + 1] = make_float64(m1);
- env->vfp.regs[rd] = make_float64(d0);
- env->vfp.regs[rd + 1] = make_float64(d1);
- } else {
- uint64_t zm = float64_val(env->vfp.regs[rm]);
- uint64_t zd = float64_val(env->vfp.regs[rd]);
- uint64_t m = 0, d = 0;
- switch (size) {
- case 0:
- d = ELEM(zd, 0, 8) | (ELEM(zm, 0, 8) << 8)
- | (ELEM(zd, 1, 8) << 16) | (ELEM(zm, 1, 8) << 24)
- | (ELEM(zd, 2, 8) << 32) | (ELEM(zm, 2, 8) << 40)
- | (ELEM(zd, 3, 8) << 48) | (ELEM(zm, 3, 8) << 56);
- m = ELEM(zd, 4, 8) | (ELEM(zm, 4, 8) << 8)
- | (ELEM(zd, 5, 8) << 16) | (ELEM(zm, 5, 8) << 24)
- | (ELEM(zd, 6, 8) << 32) | (ELEM(zm, 6, 8) << 40)
- | (ELEM(zd, 7, 8) << 48) | (ELEM(zm, 7, 8) << 56);
- break;
- case 1:
- d = ELEM(zd, 0, 16) | (ELEM(zm, 0, 16) << 16)
- | (ELEM(zd, 1, 16) << 32) | (ELEM(zm, 1, 16) << 48);
- m = ELEM(zd, 2, 16) | (ELEM(zm, 2, 16) << 16)
- | (ELEM(zd, 3, 16) << 32) | (ELEM(zm, 3, 16) << 48);
- break;
- default:
- /* size == 2 is a no-op for doubleword vectors */
- break;
- }
- env->vfp.regs[rm] = make_float64(m);
- env->vfp.regs[rd] = make_float64(d);
- }
-}
return ((uint32_t)x >> shift) | (x << (32 - shift));
}
}
-
-uint64_t HELPER(neon_add_saturate_s64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- res = src1 + src2;
- if (((res ^ src1) & SIGNBIT64) && !((src1 ^ src2) & SIGNBIT64)) {
- env->QF = 1;
- res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
- }
- return res;
-}
-
-uint64_t HELPER(neon_add_saturate_u64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- res = src1 + src2;
- if (res < src1) {
- env->QF = 1;
- res = ~(uint64_t)0;
- }
- return res;
-}
-
-uint64_t HELPER(neon_sub_saturate_s64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- res = src1 - src2;
- if (((res ^ src1) & SIGNBIT64) && ((src1 ^ src2) & SIGNBIT64)) {
- env->QF = 1;
- res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
- }
- return res;
-}
-
-uint64_t HELPER(neon_sub_saturate_u64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- if (src1 < src2) {
- env->QF = 1;
- res = 0;
- } else {
- res = src1 - src2;
- }
- return res;
-}
-
-void HELPER(neon_vldst_all)(CPUState *env, uint32_t insn)
-{
-#if defined(CONFIG_USER_ONLY)
-#define LDB(addr) ldub(addr)
-#define LDW(addr) lduw(addr)
-#define LDL(addr) ldl(addr)
-#define LDQ(addr) ldq(addr)
-#define STB(addr, val) stb(addr, val)
-#define STW(addr, val) stw(addr, val)
-#define STL(addr, val) stl(addr, val)
-#define STQ(addr, val) stq(addr, val)
-#else
- int user = cpu_mmu_index(env);
-#define LDB(addr) slow_ldb_mmu(addr, user, GETPC())
-#define LDW(addr) slow_ldw_mmu(addr, user, GETPC())
-#define LDL(addr) slow_ldl_mmu(addr, user, GETPC())
-#define LDQ(addr) slow_ldq_mmu(addr, user, GETPC())
-#define STB(addr, val) slow_stb_mmu(addr, val, user, GETPC())
-#define STW(addr, val) slow_stw_mmu(addr, val, user, GETPC())
-#define STL(addr, val) slow_stl_mmu(addr, val, user, GETPC())
-#define STQ(addr, val) slow_stq_mmu(addr, val, user, GETPC())
-#endif
- static const struct {
- int nregs;
- int interleave;
- int spacing;
- } neon_ls_element_type[11] = {
- {4, 4, 1},
- {4, 4, 2},
- {4, 1, 1},
- {4, 2, 1},
- {3, 3, 1},
- {3, 3, 2},
- {3, 1, 1},
- {1, 1, 1},
- {2, 2, 1},
- {2, 2, 2},
- {2, 1, 1}
- };
-
- const int op = (insn >> 8) & 0xf;
- const int size = (insn >> 6) & 3;
- int rd = ((insn >> 12) & 0x0f) | ((insn >> 18) & 0x10);
- const int rn = (insn >> 16) & 0xf;
- const int load = (insn & (1 << 21)) != 0;
- const int nregs = neon_ls_element_type[op].nregs;
- const int interleave = neon_ls_element_type[op].interleave;
- const int spacing = neon_ls_element_type[op].spacing;
- uint32_t addr = env->regs[rn];
- const int stride = (1 << size) * interleave;
- int i, reg;
- uint64_t tmp64;
-
- for (reg = 0; reg < nregs; reg++) {
- if (interleave > 2 || (interleave == 2 && nregs == 2)) {
- addr = env->regs[rn] + (1 << size) * reg;
- } else if (interleave == 2 && nregs == 4 && reg == 2) {
- addr = env->regs[rn] + (1 << size);
- }
- switch (size) {
- case 3:
- if (load) {
- env->vfp.regs[rd] = make_float64(LDQ(addr));
- } else {
- STQ(addr, float64_val(env->vfp.regs[rd]));
- }
- addr += stride;
- break;
- case 2:
- if (load) {
- tmp64 = (uint32_t)LDL(addr);
- addr += stride;
- tmp64 |= (uint64_t)LDL(addr) << 32;
- addr += stride;
- env->vfp.regs[rd] = make_float64(tmp64);
- } else {
- tmp64 = float64_val(env->vfp.regs[rd]);
- STL(addr, tmp64);
- addr += stride;
- STL(addr, tmp64 >> 32);
- addr += stride;
- }
- break;
- case 1:
- if (load) {
- tmp64 = 0ull;
- for (i = 0; i < 4; i++, addr += stride) {
- tmp64 |= (uint64_t)LDW(addr) << (i * 16);
- }
- env->vfp.regs[rd] = make_float64(tmp64);
- } else {
- tmp64 = float64_val(env->vfp.regs[rd]);
- for (i = 0; i < 4; i++, addr += stride, tmp64 >>= 16) {
- STW(addr, tmp64);
- }
- }
- break;
- case 0:
- if (load) {
- tmp64 = 0ull;
- for (i = 0; i < 8; i++, addr += stride) {
- tmp64 |= (uint64_t)LDB(addr) << (i * 8);
- }
- env->vfp.regs[rd] = make_float64(tmp64);
- } else {
- tmp64 = float64_val(env->vfp.regs[rd]);
- for (i = 0; i < 8; i++, addr += stride, tmp64 >>= 8) {
- STB(addr, tmp64);
- }
- }
- break;
- }
- rd += spacing;
- }
-#undef LDB
-#undef LDW
-#undef LDL
-#undef LDQ
-#undef STB
-#undef STW
-#undef STL
-#undef STQ
-}
#define GEN_HELPER 1
#include "helpers.h"
-//#define RESOURCE_LEAK_DEBUG
-
#define ENABLE_ARCH_5J 0
#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
conditional executions state has been updated. */
#define DISAS_WFI 4
#define DISAS_SWI 5
-#define DISAS_SMC 6
static TCGv_ptr cpu_env;
/* We reuse the same 64-bit temporaries for efficiency. */
#include "helpers.h"
}
-#ifdef RESOURCE_LEAK_DEBUG
static int num_temps;
/* Allocate a temporary variable. */
-static inline TCGv_i32 new_tmp(void)
+static TCGv_i32 new_tmp(void)
{
num_temps++;
return tcg_temp_new_i32();
}
-static inline TCGv_i32 new_tmplocal32(void)
-{
- num_temps++;
- return tcg_temp_local_new_i32();
-}
-
-static inline TCGv new_tmplocal(void)
-{
- num_temps++;
- return tcg_temp_local_new();
-}
-
-static inline TCGv_i64 new_tmp64(void)
-{
- num_temps++;
- return tcg_temp_new_i64();
-}
-
-static inline TCGv_ptr new_tmpptr(void)
-{
- num_temps++;
- return tcg_temp_new_ptr();
-}
-
-static inline TCGv_i32 new_const(uint32_t value)
-{
- num_temps++;
- return tcg_const_i32(value);
-}
-
-static inline TCGv_i64 new_const64(uint64_t value)
-{
- num_temps++;
- return tcg_const_i64(value);
-}
-
/* Release a temporary variable. */
-static inline void dead_tmp(TCGv tmp)
-{
- tcg_temp_free_i32(tmp);
- num_temps--;
-}
-
-static inline void dead_tmp64(TCGv_i64 tmp)
-{
- tcg_temp_free_i64(tmp);
- num_temps--;
-}
-
-static inline void dead_tmp_(TCGv tmp)
+static void dead_tmp(TCGv tmp)
{
tcg_temp_free(tmp);
num_temps--;
}
-static inline void dead_tmpptr(TCGv_ptr tmp)
-{
- tcg_temp_free_ptr(tmp);
- num_temps--;
-}
-
-#undef tcg_temp_local_new
-#undef tcg_temp_new_ptr
-#undef tcg_temp_free
-#undef tcg_temp_free_ptr
-#define tcg_temp_new_i32() new_tmp()
-#define tcg_temp_new_i64() new_tmp64()
-#define tcg_temp_local_new() new_tmplocal()
-#define tcg_temp_local_new_i32() new_tmplocal32()
-#define tcg_temp_new_ptr() new_tmpptr()
-#define tcg_const_i32(x) new_const(x)
-#define tcg_const_i64(x) new_const64(x)
-#define tcg_temp_free(x) dead_tmp_(x)
-#define tcg_temp_free_i32(x) dead_tmp(x)
-#define tcg_temp_free_i64(x) dead_tmp64(x)
-#define tcg_temp_free_ptr(x) dead_tmpptr(x)
-#else // RESOURCE_LEAK_DEBUG
-#define new_tmp() tcg_temp_new_i32()
-#define dead_tmp(x) tcg_temp_free_i32(x)
-#endif // RESOOURCE_LEAK_DEBUG
-
static inline TCGv load_cpu_offset(int offset)
{
TCGv tmp = new_tmp();
}
}
-static inline void gen_smc(CPUState *env, DisasContext *s)
-{
- tcg_gen_movi_i32(cpu_R[15], s->pc);
- s->is_jmp = DISAS_SMC;
-}
-
static inline TCGv gen_ld8s(TCGv addr, int index)
{
TCGv tmp = new_tmp();
TCGV_UNUSED(tmp3);
}
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
- tcg_temp_free_i32(tmp3);
- tcg_temp_free_i32(tmp2);
+ tcg_temp_free(tmp3);
+ tcg_temp_free(tmp2);
dead_tmp(tmp);
gen_op_iwmmxt_movq_wRn_M0(wrd);
gen_op_iwmmxt_set_mup();
tmp = tcg_const_i32((insn >> 20) & 3);
iwmmxt_load_reg(cpu_V1, rd1);
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
- tcg_temp_free_i32(tmp);
+ tcg_temp_free(tmp);
gen_op_iwmmxt_movq_wRn_M0(wrd);
gen_op_iwmmxt_set_mup();
break;
gen_op_iwmmxt_movq_M0_wRn(rd0);
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
- tcg_temp_free_i32(tmp);
+ tcg_temp_free(tmp);
gen_op_iwmmxt_movq_wRn_M0(wrd);
gen_op_iwmmxt_set_mup();
gen_op_iwmmxt_set_cup();
tmp = new_tmp();
tmp2 = tcg_const_i32(insn);
gen_helper_get_cp(tmp, cpu_env, tmp2);
- tcg_temp_free_i32(tmp2);
+ tcg_temp_free(tmp2);
store_reg(s, rd, tmp);
} else {
if (!env->cp[cp].cp_write)
tmp = load_reg(s, rd);
tmp2 = tcg_const_i32(insn);
gen_helper_set_cp(cpu_env, tmp2, tmp);
- tcg_temp_free_i32(tmp2);
+ tcg_temp_free(tmp2);
dead_tmp(tmp);
}
return 0;
offset = 8;
else
offset = 4;
- tmp = tcg_const_i32(offset);
for (i = 0; i < n; i++) {
if (insn & ARM_CP_RW_BIT) {
/* load */
gen_mov_F0_vreg(dp, rd + i);
gen_vfp_st(s, dp, addr);
}
- tcg_gen_add_i32(addr, addr, tmp);
+ tcg_gen_addi_i32(addr, addr, offset);
}
- tcg_temp_free_i32(tmp);
if (insn & (1 << 21)) {
/* writeback */
if (insn & (1 << 24))
s->is_jmp = DISAS_JUMP;
}
-static inline void
-gen_save_condexec (DisasContext *s)
-{
- uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_cpu_field(tmp, actual_condexec_bits);
-}
-
static void gen_nop_hint(DisasContext *s, int val)
{
switch (val) {
return tmp;
}
+static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
+{
+ TCGv rd, rm, tmp;
+
+ rd = new_tmp();
+ rm = new_tmp();
+ tmp = new_tmp();
+
+ tcg_gen_andi_i32(rd, t0, 0xff);
+ tcg_gen_shri_i32(tmp, t0, 8);
+ tcg_gen_andi_i32(tmp, tmp, 0xff00);
+ tcg_gen_or_i32(rd, rd, tmp);
+ tcg_gen_shli_i32(tmp, t1, 16);
+ tcg_gen_andi_i32(tmp, tmp, 0xff0000);
+ tcg_gen_or_i32(rd, rd, tmp);
+ tcg_gen_shli_i32(tmp, t1, 8);
+ tcg_gen_andi_i32(tmp, tmp, 0xff000000);
+ tcg_gen_or_i32(rd, rd, tmp);
+
+ tcg_gen_shri_i32(rm, t0, 8);
+ tcg_gen_andi_i32(rm, rm, 0xff);
+ tcg_gen_shri_i32(tmp, t0, 16);
+ tcg_gen_andi_i32(tmp, tmp, 0xff00);
+ tcg_gen_or_i32(rm, rm, tmp);
+ tcg_gen_shli_i32(tmp, t1, 8);
+ tcg_gen_andi_i32(tmp, tmp, 0xff0000);
+ tcg_gen_or_i32(rm, rm, tmp);
+ tcg_gen_andi_i32(tmp, t1, 0xff000000);
+ tcg_gen_or_i32(t1, rm, tmp);
+ tcg_gen_mov_i32(t0, rd);
+
+ dead_tmp(tmp);
+ dead_tmp(rm);
+ dead_tmp(rd);
+}
+
+static void gen_neon_zip_u8(TCGv t0, TCGv t1)
+{
+ TCGv rd, rm, tmp;
+
+ rd = new_tmp();
+ rm = new_tmp();
+ tmp = new_tmp();
+
+ tcg_gen_andi_i32(rd, t0, 0xff);
+ tcg_gen_shli_i32(tmp, t1, 8);
+ tcg_gen_andi_i32(tmp, tmp, 0xff00);
+ tcg_gen_or_i32(rd, rd, tmp);
+ tcg_gen_shli_i32(tmp, t0, 16);
+ tcg_gen_andi_i32(tmp, tmp, 0xff0000);
+ tcg_gen_or_i32(rd, rd, tmp);
+ tcg_gen_shli_i32(tmp, t1, 24);
+ tcg_gen_andi_i32(tmp, tmp, 0xff000000);
+ tcg_gen_or_i32(rd, rd, tmp);
+
+ tcg_gen_andi_i32(rm, t1, 0xff000000);
+ tcg_gen_shri_i32(tmp, t0, 8);
+ tcg_gen_andi_i32(tmp, tmp, 0xff0000);
+ tcg_gen_or_i32(rm, rm, tmp);
+ tcg_gen_shri_i32(tmp, t1, 8);
+ tcg_gen_andi_i32(tmp, tmp, 0xff00);
+ tcg_gen_or_i32(rm, rm, tmp);
+ tcg_gen_shri_i32(tmp, t0, 16);
+ tcg_gen_andi_i32(tmp, tmp, 0xff);
+ tcg_gen_or_i32(t1, rm, tmp);
+ tcg_gen_mov_i32(t0, rd);
+
+ dead_tmp(tmp);
+ dead_tmp(rm);
+ dead_tmp(rd);
+}
+
+static void gen_neon_zip_u16(TCGv t0, TCGv t1)
+{
+ TCGv tmp, tmp2;
+
+ tmp = new_tmp();
+ tmp2 = new_tmp();
+
+ tcg_gen_andi_i32(tmp, t0, 0xffff);
+ tcg_gen_shli_i32(tmp2, t1, 16);
+ tcg_gen_or_i32(tmp, tmp, tmp2);
+ tcg_gen_andi_i32(t1, t1, 0xffff0000);
+ tcg_gen_shri_i32(tmp2, t0, 16);
+ tcg_gen_or_i32(t1, t1, tmp2);
+ tcg_gen_mov_i32(t0, tmp);
+
+ dead_tmp(tmp2);
+ dead_tmp(tmp);
+}
+
+static void gen_neon_unzip(int reg, int q, int tmp, int size)
+{
+ int n;
+ TCGv t0, t1;
+
+ for (n = 0; n < q + 1; n += 2) {
+ t0 = neon_load_reg(reg, n);
+ t1 = neon_load_reg(reg, n + 1);
+ switch (size) {
+ case 0: gen_neon_unzip_u8(t0, t1); break;
+ case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same. */
+ case 2: /* no-op */; break;
+ default: abort();
+ }
+ neon_store_scratch(tmp + n, t0);
+ neon_store_scratch(tmp + n + 1, t1);
+ }
+}
+
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
{
TCGv rd, tmp;
dead_tmp(rd);
}
+
static struct {
int nregs;
int interleave;
int pass;
int load;
int shift;
+ int n;
TCGv addr;
TCGv tmp;
TCGv tmp2;
+ TCGv_i64 tmp64;
if (!s->vfp_enabled)
return 1;
/* Load store all elements. */
op = (insn >> 8) & 0xf;
size = (insn >> 6) & 3;
- if (op > 10) {
- dead_tmp(addr);
+ if (op > 10)
return 1;
- }
nregs = neon_ls_element_type[op].nregs;
interleave = neon_ls_element_type[op].interleave;
spacing = neon_ls_element_type[op].spacing;
- if (size == 3 && (interleave | spacing) != 1) {
- dead_tmp(addr);
+ if (size == 3 && (interleave | spacing) != 1)
return 1;
+ load_reg_var(s, addr, rn);
+ stride = (1 << size) * interleave;
+ for (reg = 0; reg < nregs; reg++) {
+ if (interleave > 2 || (interleave == 2 && nregs == 2)) {
+ load_reg_var(s, addr, rn);
+ tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
+ } else if (interleave == 2 && nregs == 4 && reg == 2) {
+ load_reg_var(s, addr, rn);
+ tcg_gen_addi_i32(addr, addr, 1 << size);
+ }
+ if (size == 3) {
+ if (load) {
+ tmp64 = gen_ld64(addr, IS_USER(s));
+ neon_store_reg64(tmp64, rd);
+ tcg_temp_free_i64(tmp64);
+ } else {
+ tmp64 = tcg_temp_new_i64();
+ neon_load_reg64(tmp64, rd);
+ gen_st64(tmp64, addr, IS_USER(s));
+ }
+ tcg_gen_addi_i32(addr, addr, stride);
+ } else {
+ for (pass = 0; pass < 2; pass++) {
+ if (size == 2) {
+ if (load) {
+ tmp = gen_ld32(addr, IS_USER(s));
+ neon_store_reg(rd, pass, tmp);
+ } else {
+ tmp = neon_load_reg(rd, pass);
+ gen_st32(tmp, addr, IS_USER(s));
+ }
+ tcg_gen_addi_i32(addr, addr, stride);
+ } else if (size == 1) {
+ if (load) {
+ tmp = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_addi_i32(addr, addr, stride);
+ tmp2 = gen_ld16u(addr, IS_USER(s));
+ tcg_gen_addi_i32(addr, addr, stride);
+ tcg_gen_shli_i32(tmp2, tmp2, 16);
+ tcg_gen_or_i32(tmp, tmp, tmp2);
+ dead_tmp(tmp2);
+ neon_store_reg(rd, pass, tmp);
+ } else {
+ tmp = neon_load_reg(rd, pass);
+ tmp2 = new_tmp();
+ tcg_gen_shri_i32(tmp2, tmp, 16);
+ gen_st16(tmp, addr, IS_USER(s));
+ tcg_gen_addi_i32(addr, addr, stride);
+ gen_st16(tmp2, addr, IS_USER(s));
+ tcg_gen_addi_i32(addr, addr, stride);
+ }
+ } else /* size == 0 */ {
+ if (load) {
+ TCGV_UNUSED(tmp2);
+ for (n = 0; n < 4; n++) {
+ tmp = gen_ld8u(addr, IS_USER(s));
+ tcg_gen_addi_i32(addr, addr, stride);
+ if (n == 0) {
+ tmp2 = tmp;
+ } else {
+ tcg_gen_shli_i32(tmp, tmp, n * 8);
+ tcg_gen_or_i32(tmp2, tmp2, tmp);
+ dead_tmp(tmp);
+ }
+ }
+ neon_store_reg(rd, pass, tmp2);
+ } else {
+ tmp2 = neon_load_reg(rd, pass);
+ for (n = 0; n < 4; n++) {
+ tmp = new_tmp();
+ if (n == 0) {
+ tcg_gen_mov_i32(tmp, tmp2);
+ } else {
+ tcg_gen_shri_i32(tmp, tmp2, n * 8);
+ }
+ gen_st8(tmp, addr, IS_USER(s));
+ tcg_gen_addi_i32(addr, addr, stride);
+ }
+ dead_tmp(tmp2);
+ }
+ }
+ }
+ }
+ rd += spacing;
}
- tcg_gen_movi_i32(addr, insn);
- gen_helper_neon_vldst_all(cpu_env, addr);
stride = nregs * 8;
} else {
size = (insn >> 10) & 3;
if (size == 3) {
/* Load single element to all lanes. */
- if (!load) {
- dead_tmp(addr);
+ if (!load)
return 1;
- }
size = (insn >> 6) & 3;
nregs = ((insn >> 8) & 3) + 1;
- if (nregs == 1) {
- stride = 0;
- } else {
- stride = (insn & (1 << 5)) ? 2 : 1;
- }
+ stride = (insn & (1 << 5)) ? 2 : 1;
load_reg_var(s, addr, rn);
for (reg = 0; reg < nregs; reg++) {
switch (size) {
tmp = gen_ld32(addr, IS_USER(s));
break;
case 3:
- dead_tmp(addr);
return 1;
default: /* Avoid compiler warnings. */
abort();
}
- if (stride && reg < nregs - 1) {
- tcg_gen_addi_i32(addr, addr, 1 << size);
- } else if (!stride) {
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
- }
+ tcg_gen_addi_i32(addr, addr, 1 << size);
tmp2 = new_tmp();
tcg_gen_mov_i32(tmp2, tmp);
neon_store_reg(rd, 0, tmp2);
}
}
-static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
-{
- switch(size) {
- case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
- case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
- case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
- default: abort();
- }
-}
-
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
int q, int u)
{
} else {
if (u) {
switch (size) {
- case 1: gen_helper_neon_shl_u16(var, var, shift); break;
- case 2: gen_helper_neon_shl_u32(var, var, shift); break;
+ case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
+ case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
default: abort();
}
} else {
TCGv tmp, tmp2, tmp3, tmp4, tmp5;
TCGv_i64 tmp64;
- if (!s->vfp_enabled) {
- return 1;
- }
+ if (!s->vfp_enabled)
+ return 1;
q = (insn & (1 << 6)) != 0;
u = (insn >> 24) & 1;
VFP_DREG_D(rd, insn);
} else {
tcg_gen_add_i64(CPU_V001);
}
- neon_store_reg64(cpu_V0, rd + pass);
+ break;
+ default:
+ abort();
}
- return 0;
- }
- if (op != 3) {
- return 1;
+ neon_store_reg64(cpu_V0, rd + pass);
}
+ return 0;
}
- pairwise = 0;
switch (op) {
case 8: /* VSHL */
case 9: /* VQSHL */
rtmp = rn;
rn = rm;
rm = rtmp;
+ pairwise = 0;
}
break;
- case 19: /* VMUL */
- if (u && size) {
- return 1;
- }
- break;
- case 23: /* VPADD */
- if (u) {
- return 1;
- }
- /* fall through */
case 20: /* VPMAX */
case 21: /* VPMIN */
+ case 23: /* VPADD */
pairwise = 1;
break;
- case 22: /* VQDMULH/VQRDMULH */
- if (!size) {
- return 1;
- }
- break;
- case 26: /* VADD/VSUB/VPADD/VABD (float) */
+ case 26: /* VPADD (float) */
pairwise = (u && size < 2);
- /* fall through */
- case 27: /* VMLA/VMLS/VMUL (float) */
- if (size & 1) {
- return 1;
- }
- break;
- case 28: /* VCEQ/VCGE/VCGT (float) */
- if ((!u && size) || (size & 1)) {
- return 1;
- }
- break;
- case 29: /* VACGE/VACGT (float) */
- if (!u || (size & 1)) {
- return 1;
- }
break;
case 30: /* VPMIN/VPMAX (float) */
pairwise = u;
- if (size & 1) {
- return 1;
- }
- break;
- case 31: /* VRECPS/VRSQRTS */
- if (u || (size & 1)) {
- return 1;
- }
break;
default:
+ pairwise = 0;
break;
}
- if (pairwise && q) {
- return 1;
- }
for (pass = 0; pass < (q ? 4 : 2); pass++) {
- if (pairwise) {
- /* Pairwise. */
- if (!pass) {
- tmp = neon_load_reg(rn, 0);
- tmp2 = neon_load_reg(rn, 1);
- } else {
- tmp = neon_load_reg(rm, 0);
- tmp2 = neon_load_reg(rm, 1);
- }
+
+ if (pairwise) {
+ /* Pairwise. */
+ if (q)
+ n = (pass & 1) * 2;
+ else
+ n = 0;
+ if (pass < q + 1) {
+ tmp = neon_load_reg(rn, n);
+ tmp2 = neon_load_reg(rn, n + 1);
} else {
- /* Elementwise. */
- tmp = neon_load_reg(rn, pass);
- if (rn == rm) {
- tmp2 = new_tmp();
- tcg_gen_mov_i32(tmp2, tmp);
- } else {
- tmp2 = neon_load_reg(rm, pass);
- }
+ tmp = neon_load_reg(rm, n);
+ tmp2 = neon_load_reg(rm, n + 1);
}
- switch (op) {
- case 0: /* VHADD */
- GEN_NEON_INTEGER_OP(hadd);
- break;
- case 1: /* VQADD */
- GEN_NEON_INTEGER_OP_ENV(qadd);
- break;
- case 2: /* VRHADD */
- GEN_NEON_INTEGER_OP(rhadd);
- break;
- case 3: /* Logic ops. */
- switch ((u << 2) | size) {
- case 0: /* VAND */
- tcg_gen_and_i32(tmp, tmp, tmp2);
- break;
- case 1: /* VBIC */
- tcg_gen_andc_i32(tmp, tmp, tmp2);
- break;
- case 2: /* VORR, VMOV */
- tcg_gen_or_i32(tmp, tmp, tmp2);
- break;
- case 3: /* VORN */
- tcg_gen_orc_i32(tmp, tmp, tmp2);
- break;
- case 4: /* VEOR */
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- break;
- case 5: /* VBSL */
- tmp3 = neon_load_reg(rd, pass);
- gen_neon_bsl(tmp, tmp, tmp2, tmp3);
- dead_tmp(tmp3);
- break;
- case 6: /* VBIT */
- tmp3 = neon_load_reg(rd, pass);
- gen_neon_bsl(tmp, tmp, tmp3, tmp2);
- dead_tmp(tmp3);
- break;
- case 7: /* VBIF */
- tmp3 = neon_load_reg(rd, pass);
- gen_neon_bsl(tmp, tmp3, tmp, tmp2);
- dead_tmp(tmp3);
- break;
- }
- break;
- case 4: /* VHSUB */
- GEN_NEON_INTEGER_OP(hsub);
- break;
- case 5: /* VQSUB */
- GEN_NEON_INTEGER_OP_ENV(qsub);
- break;
- case 6: /* VCGT */
- GEN_NEON_INTEGER_OP(cgt);
- break;
- case 7: /* VCGE */
- GEN_NEON_INTEGER_OP(cge);
- break;
- case 8: /* VSHL */
- GEN_NEON_INTEGER_OP(shl);
+ } else {
+ /* Elementwise. */
+ tmp = neon_load_reg(rn, pass);
+ tmp2 = neon_load_reg(rm, pass);
+ }
+ switch (op) {
+ case 0: /* VHADD */
+ GEN_NEON_INTEGER_OP(hadd);
+ break;
+ case 1: /* VQADD */
+ GEN_NEON_INTEGER_OP_ENV(qadd);
+ break;
+ case 2: /* VRHADD */
+ GEN_NEON_INTEGER_OP(rhadd);
+ break;
+ case 3: /* Logic ops. */
+ switch ((u << 2) | size) {
+ case 0: /* VAND */
+ tcg_gen_and_i32(tmp, tmp, tmp2);
break;
- case 9: /* VQSHL */
- GEN_NEON_INTEGER_OP_ENV(qshl);
+ case 1: /* BIC */
+ tcg_gen_andc_i32(tmp, tmp, tmp2);
break;
- case 10: /* VRSHL */
- GEN_NEON_INTEGER_OP(rshl);
+ case 2: /* VORR */
+ tcg_gen_or_i32(tmp, tmp, tmp2);
break;
- case 11: /* VQRSHL */
- GEN_NEON_INTEGER_OP_ENV(qrshl);
+ case 3: /* VORN */
+ tcg_gen_orc_i32(tmp, tmp, tmp2);
break;
- case 12: /* VMAX */
- GEN_NEON_INTEGER_OP(max);
+ case 4: /* VEOR */
+ tcg_gen_xor_i32(tmp, tmp, tmp2);
break;
- case 13: /* VMIN */
- GEN_NEON_INTEGER_OP(min);
+ case 5: /* VBSL */
+ tmp3 = neon_load_reg(rd, pass);
+ gen_neon_bsl(tmp, tmp, tmp2, tmp3);
+ dead_tmp(tmp3);
break;
- case 14: /* VABD */
- GEN_NEON_INTEGER_OP(abd);
+ case 6: /* VBIT */
+ tmp3 = neon_load_reg(rd, pass);
+ gen_neon_bsl(tmp, tmp, tmp3, tmp2);
+ dead_tmp(tmp3);
break;
- case 15: /* VABA */
- GEN_NEON_INTEGER_OP(abd);
- dead_tmp(tmp2);
- tmp2 = neon_load_reg(rd, pass);
- gen_neon_add(size, tmp, tmp2);
+ case 7: /* VBIF */
+ tmp3 = neon_load_reg(rd, pass);
+ gen_neon_bsl(tmp, tmp3, tmp, tmp2);
+ dead_tmp(tmp3);
break;
- case 16:
- if (!u) { /* VADD */
- if (gen_neon_add(size, tmp, tmp2)) {
- abort(); /* size == 3 is handled earlier */
- }
- } else { /* VSUB */
- switch (size) {
- case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
- default: abort(); /* size == 3 is handled earlier */
- }
+ }
+ break;
+ case 4: /* VHSUB */
+ GEN_NEON_INTEGER_OP(hsub);
+ break;
+ case 5: /* VQSUB */
+ GEN_NEON_INTEGER_OP_ENV(qsub);
+ break;
+ case 6: /* VCGT */
+ GEN_NEON_INTEGER_OP(cgt);
+ break;
+ case 7: /* VCGE */
+ GEN_NEON_INTEGER_OP(cge);
+ break;
+ case 8: /* VSHL */
+ GEN_NEON_INTEGER_OP(shl);
+ break;
+ case 9: /* VQSHL */
+ GEN_NEON_INTEGER_OP_ENV(qshl);
+ break;
+ case 10: /* VRSHL */
+ GEN_NEON_INTEGER_OP(rshl);
+ break;
+ case 11: /* VQRSHL */
+ GEN_NEON_INTEGER_OP_ENV(qrshl);
+ break;
+ case 12: /* VMAX */
+ GEN_NEON_INTEGER_OP(max);
+ break;
+ case 13: /* VMIN */
+ GEN_NEON_INTEGER_OP(min);
+ break;
+ case 14: /* VABD */
+ GEN_NEON_INTEGER_OP(abd);
+ break;
+ case 15: /* VABA */
+ GEN_NEON_INTEGER_OP(abd);
+ dead_tmp(tmp2);
+ tmp2 = neon_load_reg(rd, pass);
+ gen_neon_add(size, tmp, tmp2);
+ break;
+ case 16:
+ if (!u) { /* VADD */
+ if (gen_neon_add(size, tmp, tmp2))
+ return 1;
+ } else { /* VSUB */
+ switch (size) {
+ case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
+ case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
+ default: return 1;
}
- break;
- case 17:
- if (!u) { /* VTST */
- switch (size) {
- case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
- case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
- default: abort(); /* size == 3 is handled earlier */
- }
- } else { /* VCEQ */
- switch (size) {
- case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
- case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
- default: abort(); /* size == 3 is handled earlier */
- }
+ }
+ break;
+ case 17:
+ if (!u) { /* VTST */
+ switch (size) {
+ case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
+ case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
+ default: return 1;
}
- break;
- case 18: /* Multiply. */
+ } else { /* VCEQ */
+ switch (size) {
+ case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
+ case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
+ default: return 1;
+ }
+ }
+ break;
+ case 18: /* Multiply. */
+ switch (size) {
+ case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
+ case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
+ default: return 1;
+ }
+ dead_tmp(tmp2);
+ tmp2 = neon_load_reg(rd, pass);
+ if (u) { /* VMLS */
+ gen_neon_rsb(size, tmp, tmp2);
+ } else { /* VMLA */
+ gen_neon_add(size, tmp, tmp2);
+ }
+ break;
+ case 19: /* VMUL */
+ if (u) { /* polynomial */
+ gen_helper_neon_mul_p8(tmp, tmp, tmp2);
+ } else { /* Integer */
switch (size) {
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
- default: abort(); /* size == 3 is handled earlier */
- }
- dead_tmp(tmp2);
- tmp2 = neon_load_reg(rd, pass);
- if (u) { /* VMLS */
- gen_neon_rsb(size, tmp, tmp2);
- } else { /* VMLA */
- gen_neon_add(size, tmp, tmp2);
- }
- break;
- case 19: /* VMUL */
- if (u) { /* polynomial */
- gen_helper_neon_mul_p8(tmp, tmp, tmp2);
- } else { /* Integer */
- switch (size) {
- case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
- default: abort(); /* size == 3 is handled earlier */
- }
+ default: return 1;
}
- break;
- case 20: /* VPMAX */
- GEN_NEON_INTEGER_OP(pmax);
- break;
- case 21: /* VPMIN */
- GEN_NEON_INTEGER_OP(pmin);
- break;
- case 22: /* Multiply high. */
- if (!u) { /* VQDMULH */
- switch (size) {
- case 1:
- gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
- break;
- default:
- abort(); /* size == 0,3 is handled earlier */
- }
- } else { /* VQRDHMUL */
- switch (size) {
- case 1:
- gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
- break;
- default:
- abort(); /* size == 0,3 is handled earlier */
- }
- }
- break;
- case 23: /* VPADD */
+ }
+ break;
+ case 20: /* VPMAX */
+ GEN_NEON_INTEGER_OP(pmax);
+ break;
+ case 21: /* VPMIN */
+ GEN_NEON_INTEGER_OP(pmin);
+ break;
+ case 22: /* Hultiply high. */
+ if (!u) { /* VQDMULH */
switch (size) {
- case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
- default: abort(); /* size == 3 is handled earlier */
- }
- break;
- case 26: /* Floating point arithmetic. */
- switch ((u << 2) | size) {
- case 0: /* VADD */
- gen_helper_neon_add_f32(tmp, tmp, tmp2);
- break;
- case 2: /* VSUB */
- gen_helper_neon_sub_f32(tmp, tmp, tmp2);
- break;
- case 4: /* VPADD */
- gen_helper_neon_add_f32(tmp, tmp, tmp2);
- break;
- case 6: /* VABD */
- gen_helper_neon_abd_f32(tmp, tmp, tmp2);
- break;
- default:
- abort(); /* other values are handled earlier */
- }
- break;
- case 27: /* Float multiply. */
- gen_helper_neon_mul_f32(tmp, tmp, tmp2);
- if (!u) {
- dead_tmp(tmp2);
- tmp2 = neon_load_reg(rd, pass);
- if (size == 0) {
- gen_helper_neon_add_f32(tmp, tmp, tmp2);
- } else {
- gen_helper_neon_sub_f32(tmp, tmp2, tmp);
- }
+ case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
+ case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
+ default: return 1;
}
- break;
- case 28: /* Float compare. */
- if (!u) {
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
- } else {
- if (size == 0) {
- gen_helper_neon_cge_f32(tmp, tmp, tmp2);
- } else {
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
- }
+ } else { /* VQRDHMUL */
+ switch (size) {
+ case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
+ case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
+ default: return 1;
}
+ }
+ break;
+ case 23: /* VPADD */
+ if (u)
+ return 1;
+ switch (size) {
+ case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
+ case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
+ default: return 1;
+ }
+ break;
+ case 26: /* Floating point arithnetic. */
+ switch ((u << 2) | size) {
+ case 0: /* VADD */
+ gen_helper_neon_add_f32(tmp, tmp, tmp2);
break;
- case 29: /* Float compare absolute. */
- if (size == 0) {
- gen_helper_neon_acge_f32(tmp, tmp, tmp2);
- } else {
- gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
- }
+ case 2: /* VSUB */
+ gen_helper_neon_sub_f32(tmp, tmp, tmp2);
break;
- case 30: /* Float min/max. */
- if (size == 0) {
- gen_helper_neon_max_f32(tmp, tmp, tmp2);
- } else {
- gen_helper_neon_min_f32(tmp, tmp, tmp2);
- }
+ case 4: /* VPADD */
+ gen_helper_neon_add_f32(tmp, tmp, tmp2);
break;
- case 31:
+ case 6: /* VABD */
+ gen_helper_neon_abd_f32(tmp, tmp, tmp2);
+ break;
+ default:
+ return 1;
+ }
+ break;
+ case 27: /* Float multiply. */
+ gen_helper_neon_mul_f32(tmp, tmp, tmp2);
+ if (!u) {
+ dead_tmp(tmp2);
+ tmp2 = neon_load_reg(rd, pass);
if (size == 0) {
- gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
+ gen_helper_neon_add_f32(tmp, tmp, tmp2);
} else {
- gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
+ gen_helper_neon_sub_f32(tmp, tmp2, tmp);
}
- break;
- default:
- abort();
}
- dead_tmp(tmp2);
-
- /* Save the result. For elementwise operations we can put it
- straight into the destination register. For pairwise operations
- we have to be careful to avoid clobbering the source operands.*/
- if (pairwise && rd == rm) {
- neon_store_scratch(pass, tmp);
+ break;
+ case 28: /* Float compare. */
+ if (!u) {
+ gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
} else {
- neon_store_reg(rd, pass, tmp);
+ if (size == 0)
+ gen_helper_neon_cge_f32(tmp, tmp, tmp2);
+ else
+ gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
}
+ break;
+ case 29: /* Float compare absolute. */
+ if (!u)
+ return 1;
+ if (size == 0)
+ gen_helper_neon_acge_f32(tmp, tmp, tmp2);
+ else
+ gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
+ break;
+ case 30: /* Float min/max. */
+ if (size == 0)
+ gen_helper_neon_max_f32(tmp, tmp, tmp2);
+ else
+ gen_helper_neon_min_f32(tmp, tmp, tmp2);
+ break;
+ case 31:
+ if (size == 0)
+ gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
+ else
+ gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
+ break;
+ default:
+ abort();
+ }
+ dead_tmp(tmp2);
+
+ /* Save the result. For elementwise operations we can put it
+ straight into the destination register. For pairwise operations
+ we have to be careful to avoid clobbering the source operands. */
+ if (pairwise && rd == rm) {
+ neon_store_scratch(pass, tmp);
+ } else {
+ neon_store_reg(rd, pass, tmp);
+ }
+
} /* for pass */
if (pairwise && rd == rm) {
for (pass = 0; pass < (q ? 4 : 2); pass++) {
/* Two registers and shift. */
op = (insn >> 8) & 0xf;
if (insn & (1 << 7)) {
- if (op & 8) {
- return 1;
- }
/* 64-bit shift. */
size = 3;
} else {
size = 2;
- while ((insn & (1 << (size + 19))) == 0) {
+ while ((insn & (1 << (size + 19))) == 0)
size--;
- }
}
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
/* To avoid excessive dumplication of ops we implement shift
by immediate using the variable shift operations. */
if (op < 8) {
/* Shift by immediate:
- VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VSLI, VQSHL, VQSHLU */
+ VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
/* Right shifts are encoded as N - shift, where N is the
element size in bits. */
- if ((q && ((rd | rm) & 1))
- || (!u && (op == 4 || op == 6))) {
- return 1;
- }
- if (op <= 4) {
+ if (op <= 4)
shift = shift - (1 << (size + 3));
- }
if (size == 3) {
count = q + 1;
} else {
switch (op) {
case 0: /* VSHR */
case 1: /* VSRA */
- if (u) {
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0,
- cpu_V1);
- } else {
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0,
- cpu_V1);
- }
+ if (u)
+ gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
+ else
+ gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
break;
case 2: /* VRSHR */
case 3: /* VRSRA */
- if (u) {
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V0,
- cpu_V1);
- } else {
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V0,
- cpu_V1);
- }
+ if (u)
+ gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
+ else
+ gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
break;
case 4: /* VSRI */
+ if (!u)
+ return 1;
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
break;
case 5: /* VSHL, VSLI */
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
} else if (op == 4 || (op == 5 && u)) {
/* Insert */
- neon_load_reg64(cpu_V1, rd + pass);
- uint64_t mask;
- if (op == 4) {
- mask = 0xffffffffffffffffull >> -shift;
- } else {
- mask = 0xffffffffffffffffull << shift;
- }
- tcg_gen_andi_i64(cpu_V0, cpu_V0, mask);
- tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
+ cpu_abort(env, "VS[LR]I.64 not implemented");
}
neon_store_reg64(cpu_V0, rd + pass);
} else { /* size < 3 */
/* Operands in T0 and T1. */
tmp = neon_load_reg(rm, pass);
- tmp2 = tcg_const_i32(imm);
+ tmp2 = new_tmp();
+ tcg_gen_movi_i32(tmp2, imm);
switch (op) {
case 0: /* VSHR */
case 1: /* VSRA */
GEN_NEON_INTEGER_OP(rshl);
break;
case 4: /* VSRI */
+ if (!u)
+ return 1;
+ GEN_NEON_INTEGER_OP(shl);
+ break;
case 5: /* VSHL, VSLI */
switch (size) {
- case 0:
- gen_helper_neon_shl_u8(tmp, tmp, tmp2);
- break;
- case 1:
- gen_helper_neon_shl_u16(tmp, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_shl_u32(tmp, tmp, tmp2);
- break;
- default:
- abort(); /* size == 3 is handled earlier */
+ case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
+ case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
+ default: return 1;
}
break;
case 6: /* VQSHLU */
GEN_NEON_INTEGER_OP_ENV(qshl);
break;
}
- tcg_temp_free_i32(tmp2);
+ dead_tmp(tmp2);
if (op == 1 || op == 3) {
/* Accumulate. */
/* Insert */
switch (size) {
case 0:
- if (op == 4) {
+ if (op == 4)
mask = 0xff >> -shift;
- } else {
+ else
mask = (uint8_t)(0xff << shift);
- }
mask |= mask << 8;
mask |= mask << 16;
break;
case 1:
- if (op == 4) {
+ if (op == 4)
mask = 0xffff >> -shift;
- } else {
+ else
mask = (uint16_t)(0xffff << shift);
- }
mask |= mask << 16;
break;
case 2:
if (shift < -31 || shift > 31) {
mask = 0;
} else {
- if (op == 4) {
+ if (op == 4)
mask = 0xffffffffu >> -shift;
- } else {
+ else
mask = 0xffffffffu << shift;
- }
}
break;
default:
- abort(); /* size == 3 is handled earlier */
+ abort();
}
tmp2 = neon_load_reg(rd, pass);
tcg_gen_andi_i32(tmp, tmp, mask);
} /* for pass */
} else if (op < 10) {
/* Shift by immediate and narrow:
- VSHRN, VRSHRN, VQSHRN, VQSHRUN, VQRSHRN, VQRSHRUN */
- if (rm & 1) {
- return 1;
- }
+ VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
shift = shift - (1 << (size + 3));
size++;
switch (size) {
abort();
}
- TCGV_UNUSED(tmp5);
for (pass = 0; pass < 2; pass++) {
if (size == 3) {
neon_load_reg64(cpu_V0, rm + pass);
if (q) {
- if ((op == 8 && !u) || (op == 9 && u)) {
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V0,
- tmp64);
- } else {
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V0,
- tmp64);
- }
+ if (u)
+ gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
+ else
+ gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
} else {
- if ((op == 8 && !u) || (op == 9 && u)) {
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0,
- tmp64);
- } else {
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0,
- tmp64);
- }
+ if (u)
+ gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
+ else
+ gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
}
} else {
tmp = neon_load_reg(rm + pass, 0);
- gen_neon_shift_narrow(size, tmp, tmp2, q,
- (op == 8) ? !u : u);
+ gen_neon_shift_narrow(size, tmp, tmp2, q, u);
tmp3 = neon_load_reg(rm + pass, 1);
- gen_neon_shift_narrow(size, tmp3, tmp2, q,
- (op == 8) ? !u : u);
+ gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
dead_tmp(tmp);
dead_tmp(tmp3);
}
- tmp4 = new_tmp();
- if (op == 8) {
- if (u) { /* VQSHRUN / VQRSHRUN */
- gen_neon_unarrow_sats(size - 1, tmp4, cpu_V0);
- } else { /* VSHRN / VRSHRN */
- gen_neon_narrow(size - 1, tmp4, cpu_V0);
- }
- } else { /* VQSHRN / VQRSHRN */
- if (u) {
- gen_neon_narrow_satu(size - 1, tmp4, cpu_V0);
- } else {
- gen_neon_narrow_sats(size - 1, tmp4, cpu_V0);
- }
- }
- if (!pass) {
- tmp5 = tmp4;
+ tmp = new_tmp();
+ if (op == 8 && !u) {
+ gen_neon_narrow(size - 1, tmp, cpu_V0);
+ } else {
+ if (op == 8)
+ gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
+ else
+ gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
}
+ neon_store_reg(rd, pass, tmp);
} /* for pass */
- neon_store_reg(rd, 0, tmp5);
- neon_store_reg(rd, 1, tmp4);
if (size == 3) {
tcg_temp_free_i64(tmp64);
} else {
}
} else if (op == 10) {
/* VSHLL */
- if (q) {
+ if (q || size == 3)
return 1;
- }
tmp = neon_load_reg(rm, 0);
tmp2 = neon_load_reg(rm, 1);
for (pass = 0; pass < 2; pass++) {
- if (pass == 1) {
+ if (pass == 1)
tmp = tmp2;
- }
+
gen_neon_widen(cpu_V0, tmp, size, u);
if (shift != 0) {
/* The shift is less than the width of the source
type, so we can just shift the whole register. */
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
- if (size < 2) {
+ if (size < 2 || !u) {
uint64_t imm64;
if (size == 0) {
imm = (0xffu >> (8 - shift));
imm = 0xffff >> (16 - shift);
}
imm64 = imm | (((uint64_t)imm) << 32);
- tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
+ tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
}
}
neon_store_reg64(cpu_V0, rd + pass);
for (pass = 0; pass < (q ? 4 : 2); pass++) {
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
if (!(op & 1)) {
- if (u){
- gen_vfp_toul(0, shift);
- } else {
- gen_vfp_tosl(0, shift);
- }
- } else {
- if (u) {
+ if (u)
gen_vfp_ulto(0, shift);
- } else {
+ else
gen_vfp_slto(0, shift);
- }
+ } else {
+ if (u)
+ gen_vfp_toul(0, shift);
+ else
+ gen_vfp_tosl(0, shift);
}
- tcg_gen_st_f32(cpu_F0s, cpu_env,
- neon_reg_offset(rd, pass));
+ tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
}
} else {
return 1;
break;
case 14:
imm |= (imm << 8) | (imm << 16) | (imm << 24);
- if (invert) {
+ if (invert)
imm = ~imm;
- }
break;
case 15:
- if (invert) {
- return 1;
- }
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
break;
} else { /* (insn & 0x00800010 == 0x00800000) */
if (size != 3) {
op = (insn >> 8) & 0xf;
- if (!q) {
+ if ((insn & (1 << 6)) == 0) {
/* Three registers of different lengths. */
-
- if (op == 15
- || (op < 4 && ((rd & 1) || ((op & 1) && (rn & 1))))
- || ((op == 4 || op == 6) && ((rn | rm) & 1))
- || ((op == 5 || op >= 7) && (rd & 1))
- || ((op == 9 || op == 11) && (u || size == 0))
- || (op == 13 && size == 0)
- || (op == 14 && (u || size))) {
+ int src1_wide;
+ int src2_wide;
+ int prewiden;
+ /* prewiden, src1_wide, src2_wide */
+ static const int neon_3reg_wide[16][3] = {
+ {1, 0, 0}, /* VADDL */
+ {1, 1, 0}, /* VADDW */
+ {1, 0, 0}, /* VSUBL */
+ {1, 1, 0}, /* VSUBW */
+ {0, 1, 1}, /* VADDHN */
+ {0, 0, 0}, /* VABAL */
+ {0, 1, 1}, /* VSUBHN */
+ {0, 0, 0}, /* VABDL */
+ {0, 0, 0}, /* VMLAL */
+ {0, 0, 0}, /* VQDMLAL */
+ {0, 0, 0}, /* VMLSL */
+ {0, 0, 0}, /* VQDMLSL */
+ {0, 0, 0}, /* Integer VMULL */
+ {0, 0, 0}, /* VQDMULL */
+ {0, 0, 0} /* Polynomial VMULL */
+ };
+
+ prewiden = neon_3reg_wide[op][0];
+ src1_wide = neon_3reg_wide[op][1];
+ src2_wide = neon_3reg_wide[op][2];
+
+ if (size == 0 && (op == 9 || op == 11 || op == 13))
return 1;
- }
-
- int src1_wide = (op == 1 || op == 3 || op == 4 || op == 6);
- int src2_wide = (op == 4 || op == 6);
- int prewiden = (op < 4);
/* Avoid overlapping operands. Wide source operands are
always aligned so will never overlap with wide
case 5:
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
break;
- default: abort(); /* size == 3 is handled earlier */
+ default: abort();
}
dead_tmp(tmp2);
dead_tmp(tmp);
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
break;
case 14: /* Polynomial VMULL */
- gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
- dead_tmp(tmp2);
- dead_tmp(tmp);
- break;
+ cpu_abort(env, "Polynomial VMULL not implemented");
+
default: /* 15 is RESERVED. */
- abort(); /* op == 15 is handled earlier */
+ return 1;
}
if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
/* Accumulate. */
- if (op == 10) {
+ if (op == 10 || op == 11) {
gen_neon_negl(cpu_V0, size);
}
break;
case 9: case 11: /* VQDMLAL, VQDMLSL */
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- if (op == 11) {
- gen_neon_negl(cpu_V0, size);
- }
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
break;
+ /* Fall through. */
case 13: /* VQDMULL */
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
break;
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
break;
- default: abort(); /* size == 3 is handled earlier */
+ default: abort();
}
} else {
switch (size) {
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
break;
- default: abort(); /* size == 3 is handled earlier */
+ default: abort();
}
}
if (pass == 0) {
case 5: /* Floating point VMLS scalar */
case 8: /* Integer VMUL scalar */
case 9: /* Floating point VMUL scalar */
- if (size <= (op & 1)) {
- return 1;
- }
- /* fall through */
case 12: /* VQDMULH scalar */
case 13: /* VQRDMULH scalar */
- if (u && ((rd | rn) & 1)) {
- return 1;
- }
tmp = neon_get_scalar(size, rm);
neon_store_scratch(0, tmp);
for (pass = 0; pass < (u ? 4 : 2); pass++) {
tmp2 = neon_load_reg(rn, pass);
if (op == 12) {
if (size == 1) {
- gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp,
- tmp2);
- } else { /* TODO: what happens when size == 0? */
- gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp,
- tmp2);
+ gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
+ } else {
+ gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
}
} else if (op == 13) {
if (size == 1) {
- gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp,
- tmp2);
- } else { /* TODO: what happens when size == 0? */
- gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp,
- tmp2);
+ gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
+ } else {
+ gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
}
} else if (op & 1) {
gen_helper_neon_mul_f32(tmp, tmp, tmp2);
} else {
switch (size) {
- case 0:
- gen_helper_neon_mul_u8(tmp, tmp, tmp2);
- break;
- case 1:
- gen_helper_neon_mul_u16(tmp, tmp, tmp2);
- break;
- case 2:
- tcg_gen_mul_i32(tmp, tmp, tmp2);
- break;
- default:
- abort(); /* size == 3 is handled earlier */
+ case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
+ case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
+ case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
+ default: return 1;
}
}
dead_tmp(tmp2);
gen_helper_neon_sub_f32(tmp, tmp2, tmp);
break;
default:
- abort(); /* size == 3 is handled earlier */
+ abort();
}
dead_tmp(tmp2);
}
neon_store_reg(rd, pass, tmp);
}
break;
- case 3: /* VQDMLAL scalar */
- case 7: /* VQDMLSL scalar */
- case 11: /* VQDMULL scalar */
- if (u) {
- return 1;
- }
- /* fall through */
case 2: /* VMLAL sclar */
+ case 3: /* VQDMLAL scalar */
case 6: /* VMLSL scalar */
+ case 7: /* VQDMLSL scalar */
case 10: /* VMULL scalar */
- if (size == 0 || (rd & 1)) {
+ case 11: /* VQDMULL scalar */
+ if (size == 0 && (op == 3 || op == 7 || op == 11))
return 1;
- }
tmp2 = neon_get_scalar(size, rm);
/* We need a copy of tmp2 because gen_neon_mull
break;
case 3: case 7:
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- if (op == 7) {
- gen_neon_negl(cpu_V0, size);
- }
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
break;
case 10:
/* Extract. */
imm = (insn >> 8) & 0xf;
- if ((imm > 7 && !q)
- || (q && ((rd | rn | rm) & 1))) {
+ if (imm > 7 && !q)
return 1;
- }
if (imm == 0) {
neon_load_reg64(cpu_V0, rn);
/* Two register misc. */
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
size = (insn >> 18) & 3;
- if ((q && (op < 36 || op > 46) && ((rd | rm) & 1))
- || (op >= 56 && size != 2)) {
- return 1;
- }
switch (op) {
case 0: /* VREV64 */
- if (size == 3) {
+ if (size == 3)
return 1;
- }
for (pass = 0; pass < (q ? 2 : 1); pass++) {
tmp = neon_load_reg(rm, pass * 2);
tmp2 = neon_load_reg(rm, pass * 2 + 1);
break;
case 4: case 5: /* VPADDL */
case 12: case 13: /* VPADAL */
- if (size == 3) {
+ if (size == 3)
return 1;
- }
for (pass = 0; pass < q + 1; pass++) {
tmp = neon_load_reg(rm, pass * 2);
gen_neon_widen(cpu_V0, tmp, size, op & 1);
}
break;
case 33: /* VTRN */
- switch (size) {
- case 0: case 1:
- goto elementwise;
- case 2:
+ if (size == 2) {
for (n = 0; n < (q ? 4 : 2); n += 2) {
tmp = neon_load_reg(rm, n);
tmp2 = neon_load_reg(rd, n + 1);
neon_store_reg(rm, n, tmp2);
neon_store_reg(rd, n + 1, tmp);
}
- break;
- default:
- return 1;
+ } else {
+ goto elementwise;
}
break;
case 34: /* VUZP */
- if (size == 3 || (!q && size == 2)) {
+ /* Reg Before After
+ Rd A3 A2 A1 A0 B2 B0 A2 A0
+ Rm B3 B2 B1 B0 B3 B1 A3 A1
+ */
+ if (size == 3)
return 1;
+ gen_neon_unzip(rd, q, 0, size);
+ gen_neon_unzip(rm, q, 4, size);
+ if (q) {
+ static int unzip_order_q[8] =
+ {0, 2, 4, 6, 1, 3, 5, 7};
+ for (n = 0; n < 8; n++) {
+ int reg = (n < 4) ? rd : rm;
+ tmp = neon_load_scratch(unzip_order_q[n]);
+ neon_store_reg(reg, n % 4, tmp);
+ }
+ } else {
+ static int unzip_order[4] =
+ {0, 4, 1, 5};
+ for (n = 0; n < 4; n++) {
+ int reg = (n < 2) ? rd : rm;
+ tmp = neon_load_scratch(unzip_order[n]);
+ neon_store_reg(reg, n % 2, tmp);
+ }
}
- tmp = tcg_const_i32(insn);
- gen_helper_neon_unzip(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
break;
case 35: /* VZIP */
- if (size == 3 || (!q && size == 2)) {
+ /* Reg Before After
+ Rd A3 A2 A1 A0 B1 A1 B0 A0
+ Rm B3 B2 B1 B0 B3 A3 B2 A2
+ */
+ if (size == 3)
return 1;
+ count = (q ? 4 : 2);
+ for (n = 0; n < count; n++) {
+ tmp = neon_load_reg(rd, n);
+ tmp2 = neon_load_reg(rd, n);
+ switch (size) {
+ case 0: gen_neon_zip_u8(tmp, tmp2); break;
+ case 1: gen_neon_zip_u16(tmp, tmp2); break;
+ case 2: /* no-op */; break;
+ default: abort();
+ }
+ neon_store_scratch(n * 2, tmp);
+ neon_store_scratch(n * 2 + 1, tmp2);
+ }
+ for (n = 0; n < count * 2; n++) {
+ int reg = (n < count) ? rd : rm;
+ tmp = neon_load_scratch(n);
+ neon_store_reg(reg, n % count, tmp);
}
- tmp = tcg_const_i32(insn);
- gen_helper_neon_zip(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
break;
case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
- if (size == 3 || (rm & 1)) {
+ if (size == 3)
return 1;
- }
TCGV_UNUSED(tmp2);
for (pass = 0; pass < 2; pass++) {
neon_load_reg64(cpu_V0, rm + pass);
tmp = new_tmp();
- if (op == 36) {
- if (q) { /* VQMOVUN */
- gen_neon_unarrow_sats(size, tmp, cpu_V0);
- } else { /* VMOVN */
- gen_neon_narrow(size, tmp, cpu_V0);
- }
- } else { /* VQMOVN */
- if (q) {
- gen_neon_narrow_satu(size, tmp, cpu_V0);
- } else {
- gen_neon_narrow_sats(size, tmp, cpu_V0);
- }
+ if (op == 36 && q == 0) {
+ gen_neon_narrow(size, tmp, cpu_V0);
+ } else if (q) {
+ gen_neon_narrow_satu(size, tmp, cpu_V0);
+ } else {
+ gen_neon_narrow_sats(size, tmp, cpu_V0);
}
if (pass == 0) {
tmp2 = tmp;
}
break;
case 38: /* VSHLL */
- if (q || size == 3 || (rd & 1)) {
+ if (q || size == 3)
return 1;
- }
tmp = neon_load_reg(rm, 0);
tmp2 = neon_load_reg(rm, 1);
for (pass = 0; pass < 2; pass++) {
- if (pass == 1) {
+ if (pass == 1)
tmp = tmp2;
- }
gen_neon_widen(cpu_V0, tmp, size, 1);
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
neon_store_reg64(cpu_V0, rd + pass);
}
break;
case 44: /* VCVT.F16.F32 */
- if (!arm_feature(env, ARM_FEATURE_VFP_FP16)
- || q || size != 1 || (rm & 1)) {
- return 1;
- }
+ if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
+ return 1;
tmp = new_tmp();
tmp2 = new_tmp();
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
dead_tmp(tmp);
break;
case 46: /* VCVT.F32.F16 */
- if (!arm_feature(env, ARM_FEATURE_VFP_FP16)
- || q || size != 1 || (rd & 1)) {
- return 1;
- }
+ if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
+ return 1;
tmp3 = new_tmp();
tmp = neon_load_reg(rm, 0);
tmp2 = neon_load_reg(rm, 1);
switch (size) {
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
case 1: gen_swap_half(tmp); break;
- default: dead_tmp(tmp); return 1;
+ default: return 1;
}
break;
case 2: /* VREV16 */
- if (size != 0) {
- dead_tmp(tmp);
+ if (size != 0)
return 1;
- }
gen_rev16(tmp);
break;
- case 8: /* VCLS */
+ case 8: /* CLS */
switch (size) {
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
- default: dead_tmp(tmp); return 1;
+ default: return 1;
}
break;
- case 9: /* VCLZ */
+ case 9: /* CLZ */
switch (size) {
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
case 2: gen_helper_clz(tmp, tmp); break;
- default: dead_tmp(tmp); return 1;
+ default: return 1;
}
break;
- case 10: /* VCNT */
- if (size != 0) {
- dead_tmp(tmp);
+ case 10: /* CNT */
+ if (size != 0)
return 1;
- }
gen_helper_neon_cnt_u8(tmp, tmp);
break;
- case 11: /* VMVN */
- if (size != 0) {
- dead_tmp(tmp);
+ case 11: /* VNOT */
+ if (size != 0)
return 1;
- }
tcg_gen_not_i32(tmp, tmp);
break;
case 14: /* VQABS */
case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
- default: dead_tmp(tmp); return 1;
+ default: return 1;
}
break;
case 15: /* VQNEG */
case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
- default: dead_tmp(tmp); return 1;
+ default: return 1;
}
break;
case 16: case 19: /* VCGT #0, VCLE #0 */
tmp2 = tcg_const_i32(0);
- switch (size) {
+ switch(size) {
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
- default: tcg_temp_free_i32(tmp2); dead_tmp(tmp); return 1;
+ default: return 1;
}
- tcg_temp_free_i32(tmp2);
- if (op == 19) {
+ tcg_temp_free(tmp2);
+ if (op == 19)
tcg_gen_not_i32(tmp, tmp);
- }
break;
case 17: case 20: /* VCGE #0, VCLT #0 */
tmp2 = tcg_const_i32(0);
- switch (size) {
+ switch(size) {
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
- default: tcg_temp_free_i32(tmp2); dead_tmp(tmp); return 1;
+ default: return 1;
}
- tcg_temp_free_i32(tmp2);
- if (op == 20) {
+ tcg_temp_free(tmp2);
+ if (op == 20)
tcg_gen_not_i32(tmp, tmp);
- }
break;
case 18: /* VCEQ #0 */
tmp2 = tcg_const_i32(0);
- switch (size) {
+ switch(size) {
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
- default: tcg_temp_free_i32(tmp2); dead_tmp(tmp); return 1;
+ default: return 1;
}
- tcg_temp_free_i32(tmp2);
+ tcg_temp_free(tmp2);
break;
case 22: /* VABS */
- switch (size) {
+ switch(size) {
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
case 2: tcg_gen_abs_i32(tmp, tmp); break;
- default: dead_tmp(tmp); return 1;
+ default: return 1;
}
break;
case 23: /* VNEG */
- if (size == 3) {
- dead_tmp(tmp);
+ if (size == 3)
return 1;
- }
tmp2 = tcg_const_i32(0);
gen_neon_rsb(size, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
+ tcg_temp_free(tmp2);
break;
case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
- if (size != 2) {
- dead_tmp(tmp);
- return 1;
- }
tmp2 = tcg_const_i32(0);
gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
- if (op == 27) {
+ tcg_temp_free(tmp2);
+ if (op == 27)
tcg_gen_not_i32(tmp, tmp);
- }
break;
case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
- if (size != 2) {
- dead_tmp(tmp);
- return 1;
- }
tmp2 = tcg_const_i32(0);
gen_helper_neon_cge_f32(tmp, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
- if (op == 28) {
+ tcg_temp_free(tmp2);
+ if (op == 28)
tcg_gen_not_i32(tmp, tmp);
- }
break;
case 26: /* Float VCEQ #0 */
- if (size != 2) {
- dead_tmp(tmp);
- return 1;
- }
tmp2 = tcg_const_i32(0);
gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
+ tcg_temp_free(tmp2);
break;
case 30: /* Float VABS */
- if (size != 2) {
- return 1;
- }
gen_vfp_abs(0);
break;
case 31: /* Float VNEG */
- if (size != 2) {
- return 1;
- }
gen_vfp_neg(0);
break;
case 32: /* VSWP */
- if (size != 0) {
- dead_tmp(tmp);
- return 1;
- }
tmp2 = neon_load_reg(rd, pass);
neon_store_reg(rm, pass, tmp2);
break;
switch (size) {
case 0: gen_neon_trn_u8(tmp, tmp2); break;
case 1: gen_neon_trn_u16(tmp, tmp2); break;
- default: abort(); /* size == 2,3 is handled earlier */
+ case 2: abort();
+ default: return 1;
}
neon_store_reg(rm, pass, tmp2);
break;
gen_vfp_touiz(0);
break;
default:
- /* Reserved: 3, 6, 7, 21, 29, 39-43, 45, 47-55 */
- dead_tmp(tmp);
+ /* Reserved: 21, 29, 39-56 */
return 1;
}
if (op == 30 || op == 31 || op >= 58) {
} else if ((insn & (1 << 10)) == 0) {
/* VTBL, VTBX. */
n = ((insn >> 5) & 0x18) + 8;
- if (q) {
+ if (insn & (1 << 6)) {
tmp = neon_load_reg(rd, 0);
} else {
tmp = new_tmp();
tmp5 = tcg_const_i32(n);
gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
dead_tmp(tmp);
- if (q) {
+ if (insn & (1 << 6)) {
tmp = neon_load_reg(rd, 1);
} else {
tmp = new_tmp();
dead_tmp(tmp);
} else if ((insn & 0x380) == 0) {
/* VDUP */
- if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
- return 1;
- }
if (insn & (1 << 19)) {
tmp = neon_load_reg(rm, 1);
} else {
if (insn & (1 << 16)) {
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
} else if (insn & (1 << 17)) {
- if ((insn >> 18) & 1) {
+ if ((insn >> 18) & 1)
gen_neon_dup_high16(tmp);
- } else {
+ else
gen_neon_dup_low16(tmp);
- }
}
for (pass = 0; pass < (q ? 4 : 2); pass++) {
tmp2 = new_tmp();
}
if ((insn & 0x0d70f000) == 0x0550f000)
return; /* PLD */
- if ((insn & 0x0d70f000) == 0x0450f000) {
- ARCH(7);
- return; /* PLI */
- }
else if ((insn & 0x0ffffdff) == 0x01010000) {
ARCH(6);
/* setend */
}
} else if ((insn & 0x0fe00000) == 0x0c400000) {
/* Coprocessor double register transfer. */
- cpu_abort(env, "unsupported coprocessor double register transfer\n");
} else if ((insn & 0x0f000010) == 0x0e000010) {
/* Additional coprocessor register transfer. */
- if (!disas_coproc_insn(env, s, insn)) {
- return;
- }
} else if ((insn & 0x0ff10020) == 0x01000000) {
uint32_t mask;
uint32_t val;
s->condlabel = gen_new_label();
gen_test_cc(cond ^ 1, s->condlabel);
s->condjmp = 1;
- gen_save_condexec(s);
}
if ((insn & 0x0f900000) == 0x03000000) {
if ((insn & (1 << 21)) == 0) {
case 4: gen_uxtb16(tmp); break;
case 6: gen_uxtb(tmp); break;
case 7: gen_uxth(tmp); break;
- default: dead_tmp(tmp); goto illegal_op;
+ default: goto illegal_op;
}
if (rn != 15) {
tmp2 = load_reg(s, rn);
}
rn = (insn >> 16) & 0xf;
addr = load_reg(s, rn);
- tmp3 = tcg_const_i32(4);
-
+
/* compute total size */
loaded_base = 0;
TCGV_UNUSED(loaded_var);
if (insn & (1 << 23)) {
if (insn & (1 << 24)) {
/* pre increment */
- tcg_gen_add_i32(addr, addr, tmp3);
+ tcg_gen_addi_i32(addr, addr, 4);
} else {
/* post increment */
}
j++;
/* no need to add after the last transfer */
if (j != n)
- tcg_gen_add_i32(addr, addr, tmp3);
+ tcg_gen_addi_i32(addr, addr, 4);
}
}
if (insn & (1 << 21)) {
/* pre increment */
} else {
/* post increment */
- tcg_gen_add_i32(addr, addr, tmp3);
+ tcg_gen_addi_i32(addr, addr, 4);
}
} else {
if (insn & (1 << 24)) {
} else {
dead_tmp(addr);
}
- tcg_temp_free_i32(tmp3);
if (loaded_base) {
store_reg(s, rn, loaded_var);
}
tcg_gen_addi_i32(addr, addr, -offset);
}
- tmp2 = tcg_const_i32(4);
for (i = 0; i < 16; i++) {
if ((insn & (1 << i)) == 0)
continue;
tmp = load_reg(s, i);
gen_st32(tmp, addr, IS_USER(s));
}
- tcg_gen_add_i32(addr, addr, tmp2);
+ tcg_gen_addi_i32(addr, addr, 4);
}
- tcg_temp_free_i32(tmp2);
if (insn & (1 << 21)) {
/* Base register writeback. */
if (insn & (1 << 24)) {
/* Coprocessor. */
if (((insn >> 24) & 3) == 3) {
/* Translate into the equivalent ARM encoding. */
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
+ insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
if (disas_neon_data_insn(env, s, insn))
goto illegal_op;
} else {
goto illegal_op;
if (insn & (1 << 26)) {
- /* Secure monitor call / smc (v6Z) */
- if (!(env->cp15.c0_c2[4] & 0xf000) || IS_USER(s)) {
- goto illegal_op;
- }
- gen_smc(env, s);
+ /* Secure monitor call (v6Z) */
+ goto illegal_op; /* not implemented. */
} else {
op = (insn >> 20) & 7;
switch (op) {
if ((insn & (1 << 11)) == 0) {
tcg_gen_addi_i32(addr, addr, -offset);
}
- tmp2 = tcg_const_i32(4);
for (i = 0; i < 8; i++) {
if (insn & (1 << i)) {
if (insn & (1 << 11)) {
gen_st32(tmp, addr, IS_USER(s));
}
/* advance to the next address. */
- tcg_gen_add_i32(addr, addr, tmp2);
+ tcg_gen_addi_i32(addr, addr, 4);
}
}
TCGV_UNUSED(tmp);
tmp = load_reg(s, 14);
gen_st32(tmp, addr, IS_USER(s));
}
- tcg_gen_add_i32(addr, addr, tmp2);
+ tcg_gen_addi_i32(addr, addr, 4);
}
- tcg_temp_free_i32(tmp2);
if ((insn & (1 << 11)) == 0) {
tcg_gen_addi_i32(addr, addr, -offset);
}
uint32_t next_page_start;
int num_insns;
int max_insns;
- int need_to_save_condexec = 0;
-#ifdef RESOURCE_LEAK_DEBUG
- int force_asmdump = 0;
/* generate intermediate code */
num_temps = 0;
-#endif
pc_start = tb->pc;
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
- dc->thumb = env->thumb;
- /* If interrupt happens inside of an IT block new TB begins at the
- * instruction that caused it after return from ISR. To preserve
- * correct execution restore IT bits saved right before the interrupt. */
- if (env->thumb && env->saved_condexec_tb == env->regs[15]) {
- env->condexec_bits = env->saved_condexec_bits;
- env->saved_condexec_tb = 0;
- }
- dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
- dc->condexec_cond = env->condexec_bits >> 4;
#if !defined(CONFIG_USER_ONLY)
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
#endif
cpu_V1 = cpu_F1d;
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
cpu_M0 = tcg_temp_new_i64();
-#ifdef RESOURCE_LEAK_DEBUG
- num_temps = 0; /* to ignore above global temporaries from the count */
-#endif
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
lj = -1;
num_insns = 0;
complications trying to do it at the end of the block. */
if (dc->condexec_mask || dc->condexec_cond)
{
- if (env->condexec_bits) {
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- store_cpu_field(tmp, condexec_bits);
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, env->condexec_bits);
- store_cpu_field(tmp, actual_condexec_bits);
- }
- }
+ TCGv tmp = new_tmp();
+ tcg_gen_movi_i32(tmp, 0);
+ store_cpu_field(tmp, condexec_bits);
+ }
do {
#ifdef CONFIG_USER_ONLY
/* Intercept jump to the magic kernel page. */
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
if (dc->condexec_mask == 0) {
dc->condexec_cond = 0;
- /* Clear saved condexec.
- * Code to clear is inserted after the last label. */
- need_to_save_condexec = 1;
}
}
} else {
disas_arm_insn(env, dc);
}
-#ifdef RESOURCE_LEAK_DEBUG
if (num_temps) {
fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
- force_asmdump = 1;
num_temps = 0;
}
-#endif
if (dc->condjmp && !dc->is_jmp) {
gen_set_label(dc->condlabel);
dc->condjmp = 0;
- if (need_to_save_condexec) {
- gen_save_condexec(dc);
- need_to_save_condexec = 0;
- }
}
/* Translation stops when a conditional branch is encountered.
* Otherwise the subsequent code could get translated several times.
gen_set_condexec(dc);
if (dc->is_jmp == DISAS_SWI) {
gen_exception(EXCP_SWI);
- } else if (dc->is_jmp == DISAS_SMC) {
- gen_exception(EXCP_SMC);
} else {
gen_exception(EXCP_DEBUG);
}
gen_set_condexec(dc);
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
gen_exception(EXCP_SWI);
- } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
- gen_exception(EXCP_SMC);
} else {
/* FIXME: Single stepping a WFI insn will not halt
the CPU. */
case DISAS_SWI:
gen_exception(EXCP_SWI);
break;
- case DISAS_SMC:
- gen_exception(EXCP_SMC);
- break;
}
if (dc->condjmp) {
gen_set_label(dc->condlabel);
gen_set_condexec(dc);
- gen_save_condexec(dc);
gen_goto_tb(dc, 1, dc->pc);
dc->condjmp = 0;
}
gen_icount_end(tb, num_insns);
*gen_opc_ptr = INDEX_op_end;
-#ifdef RESOURCE_LEAK_DEBUG
- if (force_asmdump) {
- fprintf(stderr, "----------------\n");
- fprintf(stderr, "IN: %s\n", lookup_symbol(pc_start));
- target_disas(stderr, pc_start, dc->pc - pc_start, env->thumb);
- fprintf(stderr, "\n");
- }
-#endif
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("----------------\n");
ctrl.id = qctrl_tbl[i].id;
ctrl.value = qctrl_tbl[i].init_val;
if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
- ERR("failed to set video control value while reset values : %s\n", strerror(errno));
+ ERR("failed to set video control value while reset values\n", strerror(errno));
}
}
}
void svcam_device_qctrl(SVCamState* state)
{
uint32_t i;
- char name[32] = {0,};
struct v4l2_queryctrl ctrl;
SVCamParam *param = state->thread->param;
switch (ctrl.id) {
case V4L2_CID_BRIGHTNESS:
- TRACE("Query : BRIGHTNESS\n");
- memcpy((void*)name, (void*)"brightness", 32);
i = 0;
break;
case V4L2_CID_CONTRAST:
- TRACE("Query : CONTRAST\n");
- memcpy((void*)name, (void*)"contrast", 32);
i = 1;
break;
case V4L2_CID_SATURATION:
- TRACE("Query : SATURATION\n");
- memcpy((void*)name, (void*)"saturation", 32);
i = 2;
break;
case V4L2_CID_SHARPNESS:
- TRACE("Query : SHARPNESS\n");
- memcpy((void*)name, (void*)"sharpness", 32);
i = 3;
break;
default:
param->stack[4] = SVCAM_CTRL_VALUE_MID; // default_value
param->stack[5] = ctrl.flags;
/* name field setting */
- memcpy(¶m->stack[6], (void*)name, sizeof(ctrl.name));
+ memcpy(¶m->stack[6], ctrl.name, sizeof(ctrl.name));
}
void svcam_device_s_ctrl(SVCamState* state)
switch (ctrl.id) {
case V4L2_CID_BRIGHTNESS:
i = 0;
- TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);
break;
case V4L2_CID_CONTRAST:
i = 1;
- TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);
break;
case V4L2_CID_SATURATION:
i = 2;
- TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);
break;
case V4L2_CID_SHARPNESS:
i = 3;
- TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);
break;
default:
ERR("our emulator does not support this control : 0x%x\n", ctrl.id);
ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,
qctrl_tbl[i].max, param->stack[1]);
if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
- ERR("failed to set video control value : value(%d), %s\n", strerror(errno));
+ ERR("failed to set video control value\n", strerror(errno));
param->errCode = errno;
return;
}
switch (ctrl.id) {
case V4L2_CID_BRIGHTNESS:
- TRACE("Gets the value of the BRIGHTNESS\n");
i = 0;
break;
case V4L2_CID_CONTRAST:
- TRACE("Gets the value of the CONTRAST\n");
i = 1;
break;
case V4L2_CID_SATURATION:
- TRACE("Gets the value of the SATURATION\n");
i = 2;
break;
case V4L2_CID_SHARPNESS:
- TRACE("Gets the value of the SHARPNESS\n");
i = 3;
break;
default:
}
if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {
- ERR("failed to get video control value : %s\n", strerror(errno));
+ ERR("failed to get video control value", strerror(errno));
param->errCode = errno;
return;
}
param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,
qctrl_tbl[i].max, ctrl.value);
- TRACE("Value : %d\n", param->stack[0]);
}
void svcam_device_enum_fsizes(SVCamState* state)
if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMESIZES, &fsize) < 0) {
if (errno != EINVAL)
- ERR("failed to get frame sizes : %s\n", strerror(errno));
+ ERR("failed to get frame sizes", strerror(errno));
param->errCode = errno;
return;
}
if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0) {
if (errno != EINVAL)
- ERR("failed to get frame intervals : %s\n", strerror(errno));
+ ERR("failed to get frame intervals", strerror(errno));
param->errCode = errno;
return;
}
include ./../../config-host.mak
include ./../../i386-softmmu/config-target.mak
-include ./../../arm-softmmu/config-target.mak
+#include ./../../arm-softmmu/config-target.mak
# Trick for invalid QEMU Makefile targets coming from the first include file
subdir-libhw32: all
@echo " CC $@"
$(Q)$(CC) $(CFLAGS) -o $@ -c $<
-all: $(TARGET_X86) $(TARGET_ARM) $(VTM)
+#all: $(TARGET_X86) $(TARGET_ARM)
+all: $(TARGET_X86) $(VTM)
-include $(DEPFILES)
mkdir -p $(PHONE_DIR)/x86/VMs/default
mkdir -p $(PHONE_DIR)/x86/VMs/default/logs
install emulator-x86 $(PHONE_DIR)/bin/emulator-x86
- install emulator-arm $(PHONE_DIR)/bin/emulator-arm
+# install emulator-arm $(PHONE_DIR)/bin/emulator-arm
# install savevm.glade $(PHONE_DIR)
cp -a $(VTM) $(PHONE_DIR)/bin
cp -a vtm.glade $(PHONE_DIR)/etc
MULTI_DEBUG_CHANNEL(tizen, arch_arm);
extern int sensor_update(uint16_t x, uint16_t y, uint16_t z);
-/*
+
// fake sensor_update
int sensor_update(uint16_t x, uint16_t y, uint16_t z)
{
TRACE( "x(%d), y(%d), z(%d) \n", x, y, z);
return 0;
}
-*/
+
int qemu_arch_is_arm(void)
{
return 1;
/* 1.3 target setting */
- if (strlen(startup_option.disk) > 0) {
+ if (startup_option.target != NULL) {
+ configuration.qemu_configuration.diskimg_type = 0;
+ strcpy(configuration.target_path, startup_option.target);
+
+ INFO( "target path is %s\n", configuration.target_path);
+ }
+
+ else if (strlen(startup_option.disk) > 0) {
configuration.qemu_configuration.diskimg_type = 1;
if(strcmp(SYSTEMINFO.virtual_target_name, "default") == 0)
strcpy(configuration.qemu_configuration.diskimg_path, startup_option.disk);
*/
typedef struct _STARTUP_OPTION
{
+ gchar *target; /**<Target name> */
gchar *disk; /**<Target name> */
gchar *vtm; /**<VTM name>**/
int run_level; /**<run level> */
#!/bin/sh
CURDIR=`pwd`
-$CURDIR/emulator-x86 --vtm default \
+gdb --args $CURDIR/emulator-x86 --vtm default --disk $CURDIR/../x86/VMs/default/emulimg-default.x86 \
-- -net nic,model=virtio -soundhw all -usb -usbdevice wacom-tablet -vga tizen -bios bios.bin -L $CURDIR/../x86/data/pc-bios -kernel $CURDIR/../x86/data/kernel-img/bzImage -usbdevice keyboard -rtc base=utc -net user --enable-kvm -redir tcp:1202:10.0.2.16:22
struct timeval tval;
char string[MAXBUF];
FILE *fp = NULL;
+ //int status = 0;
+ //char *name, *path;
char *info_file;
- char *arch = getenv("EMULATOR_ARCH");
- const gchar *exec_path = get_exec_path();
- if(!arch) /* for stand alone */
- {
- char *binary = g_path_get_basename(exec_path);
- if(strstr(binary, "emulator-x86"))
- arch = g_strdup_printf("x86");
- else if(strstr(binary, "emulator-arm"))
- arch = g_strdup_printf("arm");
- else
- {
- ERR( "binary setting failed\n");
- exit(1);
- }
- free(binary);
- }
GOptionEntry options[] = {
+ {"target", 0, 0, G_OPTION_ARG_STRING, &startup_option.target, "Virtual root path", "\"target path\""},
{"disk", 0, 0, G_OPTION_ARG_STRING, &startup_option.disk, "Disk image path", "\"disk path\""},
{"vtm", 0, 0, G_OPTION_ARG_STRING, &startup_option.vtm, "Virtual target image file", "\"*.x86 or *.arm\""},
{"run-level", 0, 0, G_OPTION_ARG_INT, &startup_option.run_level, "Run level", "5"},
exit(1);
}
- if (!startup_option.vtm)
- startup_option.vtm = g_strdup_printf("default");
- startup_option.disk = g_strdup_printf("%semulimg-%s.%s",virtual_target_path, startup_option.vtm, arch);
- INFO("target name :%s, disk path: %s", startup_option.vtm, startup_option.disk);
-
while(fgets(string, MAXBUF, fp)!=NULL)
INFO("%s", string);
dbg_printf("\n");
free(virtual_target_path);
free(info_file);
+ if (startup_option.target && !startup_option.disk) {
+ /* parse target option */
+ if (is_valid_target(startup_option.target) == -1) {
+ fprintf(stderr, "target path (%s) is invalid. retry target startup option\n", startup_option.target);
+ exit(1);
+ }
+ }
+ else if (startup_option.disk && !startup_option.target) {
+ /* parse disk option */
+ if (is_exist_file(startup_option.disk) != 1) {
+ fprintf(stderr, "disk image path (%s) is invalid. retry disk startup option\n", startup_option.disk);
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr, "Need exactly one of --target or --disk\n");
+ exit(1);
+ }
+
+ if (!startup_option.vtm) {
+ fprintf(stderr, "vtm image is not selected\n");
+ }
return 0;
}
if (kbd_mouse_is_absolute()) {
TRACE( "press parsing keycode = %d, result = %d\n", keycode, keycode & 0x7f);
- //ps2kbd_put_keycode(keycode & 0x7f);
+ ps2kbd_put_keycode(keycode & 0x7f);
}
}
else {
if (kbd_mouse_is_absolute()) {
TRACE( "release parsing keycode = %d, result = %d\n", keycode, keycode| 0x80);
- //ps2kbd_put_keycode(keycode | 0x80);
+ ps2kbd_put_keycode(keycode | 0x80);
}
}
}
*
*/
+
#include "vtm.h"
#include "debug_ch.h"
#ifndef _WIN32
#include <netdb.h>
#endif /* !_WIN32 */
+
//DEFAULT_DEBUG_CHANNEL(tizen);
MULTI_DEBUG_CHANNEL(tizen, emulmgr);
emul_add_opt = g_strdup_printf(" ");
if(qemu_add_opt == 0)
qemu_add_opt = g_strdup_printf(" ");
-#ifndef _WIN32
- if(strcmp(arch, "x86") == 0)
- {
- cmd = g_strdup_printf("./%s --vtm %s %s \
- -- -vga tizen -bios bios.bin -L %s/data/pc-bios -kernel %s/data/kernel-img/bzImage %s %s",
- binary, target_name, emul_add_opt, path, path, enable_kvm, qemu_add_opt);
- }
- else if(strcmp(arch,"arm")== 0)
- {
- cmd = g_strdup_printf("./%s --vtm %s %s \
- -- -kernel %s/data/kernel-img/zImage %s",
- binary, target_name, emul_add_opt, path, qemu_add_opt);
- }
- else
- {
- show_message("Error", "Architecture setting failed");
- return ;
- }
+#ifndef _WIN32
+ cmd = g_strdup_printf("./%s --vtm %s --disk %semulimg-%s.%s %s \
+ -- -vga tizen -bios bios.bin -L %s/data/pc-bios -kernel %s/data/kernel-img/bzImage %s %s",
+ binary, target_name, get_virtual_target_abs_path(target_name), target_name, arch, emul_add_opt, path, path, enable_kvm, qemu_add_opt );
#else /*_WIN32 */
- if(strcmp(arch, "x86") == 0)
- {
- cmd = g_strdup_printf("%s --vtm %s %s\
- -- -vga tizen -bios bios.bin -L %s/data/pc-bios -kernel %s/data/kernel-img/bzImage %s %s",
- binary, target_name, emul_add_opt, path, path, enable_kvm, qemu_add_opt );
- }else if(strcmp(arch, "arm") == 0)
- {
- cmd = g_strdup_printf("%s --vtm %s %s \
- -- -kernel %s/data/kernel-img/zImage %s",
- binary, target_name, emul_add_opt, path, qemu_add_opt);
- }
+ cmd = g_strdup_printf("%s --vtm %s --disk %semulimg-%s.%s %s\
+ -- -vga tizen -bios bios.bin -L %s/data/pc-bios -kernel %s/data/kernel-img/bzImage %s %s",
+ binary, target_name, get_virtual_target_abs_path(target_name), target_name , arch, emul_add_opt, path, path, enable_kvm, qemu_add_opt );
#endif
if(!g_spawn_command_line_async(cmd, &error))
char *virtual_target_path;
int info_file_status;
char full_glade_path[MAX_LEN];
- char *arch = (char*)g_getenv("EMULATOR_ARCH");
- if(arch == NULL)
- {
- ERR( "architecture setting failed\n");
- show_message("Error", "architecture setting failed");
- return ;
- }
g_create_builder = gtk_builder_new();
sprintf(full_glade_path, "%s/etc/vtm.glade", get_root_path());
add_window(sub_window, VTM_CREATE_ID);
- if(strcmp(arch, "x86") == 0)
- gtk_window_set_title(GTK_WINDOW(sub_window), "Modify existing Virtual Target(x86)");
- else if(strcmp(arch, "arm") == 0)
- gtk_window_set_title(GTK_WINDOW(sub_window), "Modify existing Virtual Target(arm)");
+ gtk_window_set_title(GTK_WINDOW(sub_window), "Modify existing Virtual Target");
virtual_target_path = get_virtual_target_abs_path(target_name);
g_info_file = g_strdup_printf("%sconfig.ini", virtual_target_path);
g_unsetenv("EMULATOR_ARCH");
g_setenv("EMULATOR_ARCH",arch,1);
INFO( "architecture : %s\n", arch);
- target_list_filepath = get_targetlist_abs_filepath();
refresh_clicked_cb(arch);
// g_free(arch);
}
char *virtual_target_path = get_virtual_target_abs_path("default");
char *info_file = g_strdup_printf("%sconfig.ini", virtual_target_path);
char *default_img_x86 = g_strdup_printf("%semulimg-default.x86", virtual_target_path);
- //make x86 default image if it's not existed.
+ char *default_img_arm = g_strdup_printf("%semulimg-default.arm", virtual_target_path);
info_file_status = is_exist_file(default_img_x86);
if(info_file_status == -1 || info_file_status == FILE_NOT_EXISTS)
{
}
set_config_value(info_file, HARDWARE_GROUP, DISK_PATH_KEY, default_img_x86);
set_config_value(info_file, HARDWARE_GROUP, BASEDISK_PATH_KEY, get_baseimg_abs_path());
-
-
- //make arm default image if it's not existed.
- g_setenv("EMULATOR_ARCH","arm",1);
- virtual_target_path = get_virtual_target_abs_path("default");
- char *default_img_arm = g_strdup_printf("%semulimg-default.arm", virtual_target_path);
- info_file = g_strdup_printf("%sconfig.ini", virtual_target_path);
info_file_status = is_exist_file(default_img_arm);
if(info_file_status == -1 || info_file_status == FILE_NOT_EXISTS)
}
set_config_value(info_file, HARDWARE_GROUP, DISK_PATH_KEY, default_img_arm);
set_config_value(info_file, HARDWARE_GROUP, BASEDISK_PATH_KEY, get_baseimg_abs_path());
- g_setenv("EMULATOR_ARCH","x86",1);
free(default_img_x86);
free(default_img_arm);
int create_config_file(gchar* filepath)
{
- char *arch = getenv("EMULATOR_ARCH");
- if(arch == NULL)
- {
- ERR( "architecture setting failed\n");
- show_message("Error", "architecture setting failed");
- return -1;
- }
FILE *fp = g_fopen(filepath, "w+");
if (fp != NULL) {
g_fprintf (fp, "\n[%s]\n", ADDITIONAL_OPTION_GROUP);
g_fprintf (fp, "%s=\n", EMULATOR_OPTION_KEY);
- if(strcmp(arch, "x86") == 0)
- g_fprintf (fp, "%s=%s\n", QEMU_OPTION_KEY,"-M tizen-x86-machine -usb -usbdevice wacom-tablet -usbdevice keyboard -net nic,model=virtio -rtc base=utc -net user");
- else if(strcmp(arch, "arm") == 0)
- g_fprintf (fp, "%s=%s\n", QEMU_OPTION_KEY," -M s5pc110 -net nic,model=s5pc1xx-usb-otg -usbdevice keyboard -rtc base=utc -net user -redir tcp:1202:10.0.2.16:22");
+ g_fprintf (fp, "%s=%s\n", QEMU_OPTION_KEY,"-M tizen-x86-machine -usb -usbdevice wacom-tablet -usbdevice keyboard -net nic,model=virtio -rtc base=utc -net user");
g_fprintf (fp, "[%s]\n", HARDWARE_GROUP);
g_fprintf (fp, "%s=\n", RESOLUTION_KEY);
g_fprintf (fp, "%s=1\n", BUTTON_TYPE_KEY);
// file chooser setup
GtkWidget *sdcard_filechooser2 = (GtkWidget *)gtk_builder_get_object(g_create_builder, "filechooserbutton2");
GtkFileFilter *filter = gtk_file_filter_new();
- gtk_file_filter_set_name(filter, "Disk Image Files");
+ gtk_file_filter_set_name(filter, "Disk Files");
char *arch = (char*)g_getenv("EMULATOR_ARCH");
if(arch == NULL)
// file chooser setup
GtkWidget *sdcard_filechooser = (GtkWidget *)gtk_builder_get_object(g_create_builder, "filechooserbutton1");
GtkFileFilter *filter = gtk_file_filter_new();
- gtk_file_filter_set_name(filter, "SD Card Image Files(*.img)");
+ gtk_file_filter_set_name(filter, "SD Card Image Files");
gtk_file_filter_add_pattern(filter, "*.img");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(sdcard_filechooser), filter);
void setup_disk_frame(void)
{
- char *arch = (char*)g_getenv("EMULATOR_ARCH");
- if(arch == NULL)
- {
- ERR( "architecture setting failed\n");
- show_message("Error", "architecture setting failed");
- return ;
- }
// radio button setup
GtkWidget *default_radiobutton = (GtkWidget *)gtk_builder_get_object(g_create_builder, "radiobutton12");
GtkWidget *select_radiobutton = (GtkWidget *)gtk_builder_get_object(g_create_builder, "radiobutton13");
// file chooser setup
- GtkWidget *disk_filechooser2 = (GtkWidget *)gtk_builder_get_object(g_create_builder, "filechooserbutton2");
+ GtkWidget *sdcard_filechooser2 = (GtkWidget *)gtk_builder_get_object(g_create_builder, "filechooserbutton2");
GtkFileFilter *filter = gtk_file_filter_new();
- if(strcmp(arch, "x86") == 0)
- {
- gtk_file_chooser_button_set_title((GtkFileChooserButton *)disk_filechooser2,"Select existing Base Image(x86)");
- gtk_file_filter_set_name(filter, "Disk Image Files(*.x86)");
- }
- else if(strcmp(arch, "arm") == 0)
+ gtk_file_filter_set_name(filter, "Disk Files");
+
+ char *arch = (char*)g_getenv("EMULATOR_ARCH");
+ if(arch == NULL)
{
- gtk_file_chooser_button_set_title((GtkFileChooserButton *)disk_filechooser2,"Select existing Base Image(arm)");
- gtk_file_filter_set_name(filter, "Disk Image Files(*.arm)");
+ ERR( "architecture setting failed\n");
+ show_message("Error", "architecture setting failed");
+ return ;
}
-
+
char *filter_pattern = g_strdup_printf("*.%s",arch);
gtk_file_filter_add_pattern(filter, filter_pattern);
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(disk_filechooser2), filter);
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(sdcard_filechooser2), filter);
set_disk_select_active_cb();
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(default_radiobutton), TRUE);
g_signal_connect(G_OBJECT(select_radiobutton), "toggled", G_CALLBACK(set_disk_select_active_cb), NULL);
g_signal_connect(G_OBJECT(default_radiobutton), "toggled", G_CALLBACK(set_disk_default_active_cb), NULL);
- g_signal_connect(G_OBJECT(disk_filechooser2), "selection-changed", G_CALLBACK(disk_file_select_cb), NULL);
+ g_signal_connect(G_OBJECT(sdcard_filechooser2), "selection-changed", G_CALLBACK(disk_file_select_cb), NULL);
}
// file chooser setup
GtkWidget *sdcard_filechooser = (GtkWidget *)gtk_builder_get_object(g_create_builder, "filechooserbutton1");
GtkFileFilter *filter = gtk_file_filter_new();
- gtk_file_filter_set_name(filter, "SD Card Image Files(*.img)");
+ gtk_file_filter_set_name(filter, "SD Card Image Files");
gtk_file_filter_add_pattern(filter, "*.img");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(sdcard_filechooser), filter);
{
const gchar *skin = NULL;
GtkWidget *sub_window;
- char *arch = (char*)g_getenv("EMULATOR_ARCH");
- if(arch == NULL)
- {
- ERR( "architecture setting failed\n");
- show_message("Error", "architecture setting failed");
- return ;
- }
g_create_builder = gtk_builder_new();
char full_glade_path[MAX_LEN];
add_window(sub_window, VTM_CREATE_ID);
- if(strcmp(arch, "x86") == 0)
- gtk_window_set_title(GTK_WINDOW(sub_window), "Create new Virtual Target(x86)");
- else if(strcmp(arch, "arm") == 0)
- gtk_window_set_title(GTK_WINDOW(sub_window), "Create new Virtual Target(arm)");
-
fill_virtual_target_info();
GtkWidget *label4 = (GtkWidget *)gtk_builder_get_object(g_create_builder, "label4");
int status;
char *skin = NULL;
char full_glade_path[MAX_LEN];
-
working_dir = g_path_get_dirname(buf);
status = g_chdir(working_dir);
if(status == -1)
</object>
<object class="GtkWindow" id="window2">
<property name="width_request">420</property>
+ <property name="title" translatable="yes">Create new Virtual Target</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window_position">center</property>
<object class="GtkFileChooserButton" id="filechooserbutton1">
<property name="width_request">150</property>
<property name="visible">True</property>
- <property name="title" translatable="yes">Select an existing SD card</property>
+ <property name="title" translatable="yes">Select an existing SD card img file(*.img)</property>
</object>
<packing>
<property name="padding">5</property>
<object class="GtkFileChooserButton" id="filechooserbutton2">
<property name="width_request">150</property>
<property name="visible">True</property>
+ <property name="title" translatable="yes">Select an existing Disk</property>
</object>
<packing>
<property name="padding">5</property>
#include "vnc-enc-tight.h"
#include "vnc-palette.h"
-typedef unsigned int uint;
-
/* Compression level stuff. The following array contains various
encoder parameters for each of 10 compression levels (0..9).
Last three parameters correspond to JPEG quality levels (0..9). */
USBPacket *packet;
USBHostDevice *hdev;
-
- int more; /* packet required multiple URBs */
} AsyncURB;
static AsyncURB *async_alloc(void)
if (p) {
switch (aurb->urb.status) {
case 0:
- p->len += aurb->urb.actual_length;
+ p->len = aurb->urb.actual_length;
if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
async_complete_ctrl(s, p);
}
break;
}
- if (!aurb->more) {
- DPRINTF("invoking packet_complete. plen = %d\n", p->len);
- usb_packet_complete(p);
- }
+ usb_packet_complete(p);
}
async_free(aurb);
static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
{
int dev_descr_len, config_descr_len;
- int interface, nb_interfaces, nb_configurations;
+ int interface, nb_interfaces;
int ret, i;
if (configuration == 0) /* address state - ignore */
if (dev_descr_len > dev->descr_len) {
goto fail;
}
- nb_configurations = dev->descr[17];
i += dev_descr_len;
while (i < dev->descr_len) {
DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
- i, dev->descr_len, dev->descr[i], dev->descr[i+1]);
+ i, dev->descr_len,
+ dev->descr[i], dev->descr[i+1]);
if (dev->descr[i+1] != USB_DT_CONFIG) {
i += dev->descr[i];
static int usb_linux_update_endp_table(USBHostDevice *s);
-/* devio.c limits single requests to 16k */
-#define MAX_USBFS_BUFFER_SIZE 16384
-
static int usb_host_handle_data(USBHostDevice *s, USBPacket *p)
{
struct usbdevfs_urb *urb;
AsyncURB *aurb;
- int ret, len;
- int rem = p->len;
- uint8_t *pbuf = p->data;
+ int ret;
- p->len = 0;
- while (rem) {
- aurb = async_alloc();
- aurb->hdev = s;
- aurb->packet = p;
+ aurb = async_alloc();
+ aurb->hdev = s;
+ aurb->packet = p;
- urb = &aurb->urb;
+ urb = &aurb->urb;
- if (p->pid == USB_TOKEN_IN) {
- urb->endpoint = p->devep | 0x80;
- } else {
- urb->endpoint = p->devep;
- }
+ if (p->pid == USB_TOKEN_IN) {
+ urb->endpoint = p->devep | 0x80;
+ } else {
+ urb->endpoint = p->devep;
+ }
- if (is_halted(s, p->devep)) {
- ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
- if (ret < 0) {
- DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
- urb->endpoint, errno);
- return USB_RET_NAK;
- }
- clear_halt(s, p->devep);
+ if (is_halted(s, p->devep)) {
+ ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
+ if (ret < 0) {
+ DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
+ urb->endpoint, errno);
+ return USB_RET_NAK;
}
+ clear_halt(s, p->devep);
+ }
- if (is_isoc(s, p->devep)) {
- /* Setup ISOC transfer */
- urb->type = USBDEVFS_URB_TYPE_ISO;
- urb->flags = USBDEVFS_URB_ISO_ASAP;
- urb->number_of_packets = 1;
- urb->iso_frame_desc[0].length = p->len;
- } else {
- /* Setup bulk transfer */
- urb->type = USBDEVFS_URB_TYPE_BULK;
- }
+ urb->buffer = p->data;
+ urb->buffer_length = p->len;
- urb->usercontext = s;
+ if (is_isoc(s, p->devep)) {
+ /* Setup ISOC transfer */
+ urb->type = USBDEVFS_URB_TYPE_ISO;
+ urb->flags = USBDEVFS_URB_ISO_ASAP;
+ urb->number_of_packets = 1;
+ urb->iso_frame_desc[0].length = p->len;
+ } else {
+ /* Setup bulk transfer */
+ urb->type = USBDEVFS_URB_TYPE_BULK;
+ }
- /* USBFS limits max request size to 16k */
- if (rem > MAX_USBFS_BUFFER_SIZE) {
- len = MAX_USBFS_BUFFER_SIZE;
- aurb->more = 1;
- } else {
- len = rem;
- aurb->more = 0;
- }
- urb->buffer_length = len;
- urb->buffer = pbuf;
+ urb->usercontext = s;
- ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
+ ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
- DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
- urb->endpoint, len, aurb);
+ DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
+ urb->endpoint, p->len, aurb);
- if (ret < 0) {
- DPRINTF("husb: submit failed. errno %d\n", errno);
- async_free(aurb);
+ if (ret < 0) {
+ DPRINTF("husb: submit failed. errno %d\n", errno);
+ async_free(aurb);
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- case EPIPE:
- default:
- return USB_RET_STALL;
- }
+ switch(errno) {
+ case ETIMEDOUT:
+ return USB_RET_NAK;
+ case EPIPE:
+ default:
+ return USB_RET_STALL;
}
-
- usb_defer_packet(p, async_cancel, aurb);
-
- pbuf += len;
- rem -= len;
}
+ usb_defer_packet(p, async_cancel, aurb);
return USB_RET_ASYNC;
}
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
-#ifdef CONFIG_GLES2
-int gles2_quality = 100;
-#endif
-
static int default_serial = 1;
static int default_parallel = 1;
static int default_virtcon = 1;
case QEMU_OPTION_smbios:
do_smbios_option(optarg);
break;
-#ifdef CONFIG_GLES2
- case QEMU_OPTION_gles2_quality:
- {
- gles2_quality = strtoul(optarg, NULL, 10);
- }
- break;
-#endif
case QEMU_OPTION_enable_kvm:
kvm_allowed = 1;
break;