Compare commits
	
		
			107 Commits
		
	
	
		
			qemu-2.0.0
			...
			pull-usb-5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					840a178c94 | ||
| 
						 | 
					409951f552 | ||
| 
						 | 
					2d03b49c3f | ||
| 
						 | 
					e44a90c596 | ||
| 
						 | 
					33bbd75a7c | ||
| 
						 | 
					5538937368 | ||
| 
						 | 
					6954a1cd97 | ||
| 
						 | 
					15e3611e1c | ||
| 
						 | 
					db302f8f93 | ||
| 
						 | 
					6619bc5c55 | ||
| 
						 | 
					103db49a10 | ||
| 
						 | 
					286226a479 | ||
| 
						 | 
					a63f9f85e3 | ||
| 
						 | 
					323a8771cf | ||
| 
						 | 
					2237094d96 | ||
| 
						 | 
					1c70aa6264 | ||
| 
						 | 
					f727d0e621 | ||
| 
						 | 
					b5cde1da0a | ||
| 
						 | 
					177311157c | ||
| 
						 | 
					7633378d5f | ||
| 
						 | 
					c29f9a0a29 | ||
| 
						 | 
					f318cec6ad | ||
| 
						 | 
					377a44ec8f | ||
| 
						 | 
					3933443e38 | ||
| 
						 | 
					19525524a7 | ||
| 
						 | 
					f32cdad55d | ||
| 
						 | 
					9449fdf61f | ||
| 
						 | 
					00a29f3ddc | ||
| 
						 | 
					85acfa9c38 | ||
| 
						 | 
					1090b9c6cc | ||
| 
						 | 
					2eef0bf821 | ||
| 
						 | 
					014406b510 | ||
| 
						 | 
					0ff644a786 | ||
| 
						 | 
					cb1fa941c1 | ||
| 
						 | 
					a50c0f5133 | ||
| 
						 | 
					52e60cdd34 | ||
| 
						 | 
					2f2a00aec9 | ||
| 
						 | 
					a65f1de982 | ||
| 
						 | 
					f502cfc207 | ||
| 
						 | 
					a0618a1990 | ||
| 
						 | 
					6cd8a2649a | ||
| 
						 | 
					7e09797c29 | ||
| 
						 | 
					aca3f40b37 | ||
| 
						 | 
					9225d739e7 | ||
| 
						 | 
					2c8dd31863 | ||
| 
						 | 
					2c7ffc414d | ||
| 
						 | 
					90e496386f | ||
| 
						 | 
					8c6afa6ab1 | ||
| 
						 | 
					00892383c9 | ||
| 
						 | 
					d4a2dc675b | ||
| 
						 | 
					8bcbf37caa | ||
| 
						 | 
					abf1172fc6 | ||
| 
						 | 
					c2b820fe58 | ||
| 
						 | 
					ccd380876b | ||
| 
						 | 
					c6138aabfb | ||
| 
						 | 
					5149e557d7 | ||
| 
						 | 
					a9e8aeb375 | ||
| 
						 | 
					b825025f08 | ||
| 
						 | 
					a056c9faa4 | ||
| 
						 | 
					3d4299f425 | ||
| 
						 | 
					dc73dfd4bc | ||
| 
						 | 
					edd8824cd4 | ||
| 
						 | 
					e81864a109 | ||
| 
						 | 
					de61d14fa7 | ||
| 
						 | 
					667b1cdd4e | ||
| 
						 | 
					9e4177ad6d | ||
| 
						 | 
					dc0c8aaf2c | ||
| 
						 | 
					ae7ab46aa8 | ||
| 
						 | 
					6f4724672c | ||
| 
						 | 
					38d195aa05 | ||
| 
						 | 
					95f72aa90a | ||
| 
						 | 
					d82b78e48b | ||
| 
						 | 
					3d9e69a238 | ||
| 
						 | 
					cae1f6f3e6 | ||
| 
						 | 
					81d8a5ee19 | ||
| 
						 | 
					c6e310d938 | ||
| 
						 | 
					d8918df577 | ||
| 
						 | 
					4ec4f0bd56 | ||
| 
						 | 
					dfeb5fe770 | ||
| 
						 | 
					929f8b5550 | ||
| 
						 | 
					8bf56493f1 | ||
| 
						 | 
					661f7fa4b0 | ||
| 
						 | 
					851627352c | ||
| 
						 | 
					50212d6346 | ||
| 
						 | 
					c2b9af1d6c | ||
| 
						 | 
					940973ae0b | ||
| 
						 | 
					8611224a7b | ||
| 
						 | 
					482f38b948 | ||
| 
						 | 
					590e5dd98f | ||
| 
						 | 
					f12d048a52 | ||
| 
						 | 
					3c99afc779 | ||
| 
						 | 
					9878d173f5 | ||
| 
						 | 
					8c6c047899 | ||
| 
						 | 
					92b3eeadd9 | ||
| 
						 | 
					edc2438512 | ||
| 
						 | 
					21e2db7260 | ||
| 
						 | 
					80fc7b1755 | ||
| 
						 | 
					5450466394 | ||
| 
						 | 
					cd82b6fb4d | ||
| 
						 | 
					715c3f60ef | ||
| 
						 | 
					28ec11bc88 | ||
| 
						 | 
					2d968ffbae | ||
| 
						 | 
					afbc0dd649 | ||
| 
						 | 
					f516a5cc05 | ||
| 
						 | 
					0a9077ea14 | ||
| 
						 | 
					775478418a | ||
| 
						 | 
					50329d3418 | 
@@ -148,16 +148,26 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
 | 
				
			|||||||
    s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;
 | 
					    s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->extent_size = le32_to_cpu(bochs.extent);
 | 
					    s->extent_size = le32_to_cpu(bochs.extent);
 | 
				
			||||||
    if (s->extent_size == 0) {
 | 
					    if (s->extent_size < BDRV_SECTOR_SIZE) {
 | 
				
			||||||
        error_setg(errp, "Extent size may not be zero");
 | 
					        /* bximage actually never creates extents smaller than 4k */
 | 
				
			||||||
        return -EINVAL;
 | 
					        error_setg(errp, "Extent size must be at least 512");
 | 
				
			||||||
 | 
					        ret = -EINVAL;
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    } else if (!is_power_of_2(s->extent_size)) {
 | 
				
			||||||
 | 
					        error_setg(errp, "Extent size %" PRIu32 " is not a power of two",
 | 
				
			||||||
 | 
					                   s->extent_size);
 | 
				
			||||||
 | 
					        ret = -EINVAL;
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
    } else if (s->extent_size > 0x800000) {
 | 
					    } else if (s->extent_size > 0x800000) {
 | 
				
			||||||
        error_setg(errp, "Extent size %" PRIu32 " is too large",
 | 
					        error_setg(errp, "Extent size %" PRIu32 " is too large",
 | 
				
			||||||
                   s->extent_size);
 | 
					                   s->extent_size);
 | 
				
			||||||
        return -EINVAL;
 | 
					        ret = -EINVAL;
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->catalog_size < bs->total_sectors / s->extent_size) {
 | 
					    if (s->catalog_size < DIV_ROUND_UP(bs->total_sectors,
 | 
				
			||||||
 | 
					                                       s->extent_size / BDRV_SECTOR_SIZE))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        error_setg(errp, "Catalog size is too small for this disk size");
 | 
					        error_setg(errp, "Catalog size is too small for this disk size");
 | 
				
			||||||
        ret = -EINVAL;
 | 
					        ret = -EINVAL;
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1233,6 +1233,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
 | 
				
			|||||||
    iscsi_readcapacity_sync(iscsilun, &local_err);
 | 
					    iscsi_readcapacity_sync(iscsilun, &local_err);
 | 
				
			||||||
    if (local_err != NULL) {
 | 
					    if (local_err != NULL) {
 | 
				
			||||||
        error_propagate(errp, local_err);
 | 
					        error_propagate(errp, local_err);
 | 
				
			||||||
 | 
					        ret = -EINVAL;
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
 | 
					    bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1876,6 +1876,10 @@ void qmp_block_commit(const char *device,
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;
 | 
					    BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!has_speed) {
 | 
				
			||||||
 | 
					        speed = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* drain all i/o before commits */
 | 
					    /* drain all i/o before commits */
 | 
				
			||||||
    bdrv_drain_all();
 | 
					    bdrv_drain_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@@ -1448,7 +1448,10 @@ done
 | 
				
			|||||||
if test "$stack_protector" != "no" ; then
 | 
					if test "$stack_protector" != "no" ; then
 | 
				
			||||||
  gcc_flags="-fstack-protector-strong -fstack-protector-all"
 | 
					  gcc_flags="-fstack-protector-strong -fstack-protector-all"
 | 
				
			||||||
  for flag in $gcc_flags; do
 | 
					  for flag in $gcc_flags; do
 | 
				
			||||||
    if compile_prog "-Werror $flag" "" ; then
 | 
					    # We need to check both a compile and a link, since some compiler
 | 
				
			||||||
 | 
					    # setups fail only on a .c->.o compile and some only at link time
 | 
				
			||||||
 | 
					    if do_cc $QEMU_CFLAGS -Werror $flag -c -o $TMPO $TMPC &&
 | 
				
			||||||
 | 
					       compile_prog "-Werror $flag" ""; then
 | 
				
			||||||
      QEMU_CFLAGS="$QEMU_CFLAGS $flag"
 | 
					      QEMU_CFLAGS="$QEMU_CFLAGS $flag"
 | 
				
			||||||
      LIBTOOLFLAGS="$LIBTOOLFLAGS -Wc,$flag"
 | 
					      LIBTOOLFLAGS="$LIBTOOLFLAGS -Wc,$flag"
 | 
				
			||||||
      break
 | 
					      break
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
CONFIG_USB_TABLET_WACOM=y
 | 
					CONFIG_USB_TABLET_WACOM=y
 | 
				
			||||||
CONFIG_USB_STORAGE_BOT=y
 | 
					CONFIG_USB_STORAGE_BOT=y
 | 
				
			||||||
CONFIG_USB_STORAGE_UAS=y
 | 
					CONFIG_USB_STORAGE_UAS=y
 | 
				
			||||||
 | 
					CONFIG_USB_STORAGE_MTP=y
 | 
				
			||||||
CONFIG_USB_SMARTCARD=y
 | 
					CONFIG_USB_SMARTCARD=y
 | 
				
			||||||
CONFIG_USB_AUDIO=y
 | 
					CONFIG_USB_AUDIO=y
 | 
				
			||||||
CONFIG_USB_SERIAL=y
 | 
					CONFIG_USB_SERIAL=y
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,6 +43,19 @@ static void cubieboard_init(QEMUMachineInitArgs *args)
 | 
				
			|||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object_property_set_int(OBJECT(&s->a10->timer), 32768, "clk0-freq", &err);
 | 
				
			||||||
 | 
					    if (err != NULL) {
 | 
				
			||||||
 | 
					        error_report("Couldn't set clk0 frequency: %s", error_get_pretty(err));
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object_property_set_int(OBJECT(&s->a10->timer), 24000000, "clk1-freq",
 | 
				
			||||||
 | 
					                            &err);
 | 
				
			||||||
 | 
					    if (err != NULL) {
 | 
				
			||||||
 | 
					        error_report("Couldn't set clk1 frequency: %s", error_get_pretty(err));
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object_property_set_bool(OBJECT(s->a10), true, "realized", &err);
 | 
					    object_property_set_bool(OBJECT(s->a10), true, "realized", &err);
 | 
				
			||||||
    if (err != NULL) {
 | 
					    if (err != NULL) {
 | 
				
			||||||
        error_report("Couldn't realize Allwinner A10: %s",
 | 
					        error_report("Couldn't realize Allwinner A10: %s",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -391,7 +391,7 @@ static void build_append_int(GArray *table, uint32_t value)
 | 
				
			|||||||
        build_append_byte(table, 0x01); /* OneOp */
 | 
					        build_append_byte(table, 0x01); /* OneOp */
 | 
				
			||||||
    } else if (value <= 0xFF) {
 | 
					    } else if (value <= 0xFF) {
 | 
				
			||||||
        build_append_value(table, value, 1);
 | 
					        build_append_value(table, value, 1);
 | 
				
			||||||
    } else if (value <= 0xFFFFF) {
 | 
					    } else if (value <= 0xFFFF) {
 | 
				
			||||||
        build_append_value(table, value, 2);
 | 
					        build_append_value(table, value, 2);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        build_append_value(table, value, 4);
 | 
					        build_append_value(table, value, 4);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x53,
 | 
					0x53,
 | 
				
			||||||
0x44,
 | 
					0x44,
 | 
				
			||||||
0x54,
 | 
					0x54,
 | 
				
			||||||
0x85,
 | 
					0x80,
 | 
				
			||||||
0x11,
 | 
					0x11,
 | 
				
			||||||
0x0,
 | 
					0x0,
 | 
				
			||||||
0x0,
 | 
					0x0,
 | 
				
			||||||
0x1,
 | 
					0x1,
 | 
				
			||||||
0x8b,
 | 
					0x60,
 | 
				
			||||||
0x42,
 | 
					0x42,
 | 
				
			||||||
0x58,
 | 
					0x58,
 | 
				
			||||||
0x50,
 | 
					0x50,
 | 
				
			||||||
@@ -31,8 +31,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x4e,
 | 
					0x4e,
 | 
				
			||||||
0x54,
 | 
					0x54,
 | 
				
			||||||
0x4c,
 | 
					0x4c,
 | 
				
			||||||
0x23,
 | 
					0x15,
 | 
				
			||||||
0x8,
 | 
					0x11,
 | 
				
			||||||
0x13,
 | 
					0x13,
 | 
				
			||||||
0x20,
 | 
					0x20,
 | 
				
			||||||
0x10,
 | 
					0x10,
 | 
				
			||||||
@@ -4010,7 +4010,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x53,
 | 
					0x53,
 | 
				
			||||||
0x1,
 | 
					0x1,
 | 
				
			||||||
0x10,
 | 
					0x10,
 | 
				
			||||||
0x47,
 | 
					0x42,
 | 
				
			||||||
0x11,
 | 
					0x11,
 | 
				
			||||||
0x5f,
 | 
					0x5f,
 | 
				
			||||||
0x53,
 | 
					0x53,
 | 
				
			||||||
@@ -4243,7 +4243,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x60,
 | 
					0x60,
 | 
				
			||||||
0x5b,
 | 
					0x5b,
 | 
				
			||||||
0x82,
 | 
					0x82,
 | 
				
			||||||
0x2e,
 | 
					0x29,
 | 
				
			||||||
0x50,
 | 
					0x50,
 | 
				
			||||||
0x52,
 | 
					0x52,
 | 
				
			||||||
0x45,
 | 
					0x45,
 | 
				
			||||||
@@ -4253,16 +4253,11 @@ static unsigned char AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x48,
 | 
					0x48,
 | 
				
			||||||
0x49,
 | 
					0x49,
 | 
				
			||||||
0x44,
 | 
					0x44,
 | 
				
			||||||
0xd,
 | 
					0xc,
 | 
				
			||||||
0x41,
 | 
					0x41,
 | 
				
			||||||
0x43,
 | 
					0xd0,
 | 
				
			||||||
0x50,
 | 
					0xa,
 | 
				
			||||||
0x49,
 | 
					0x6,
 | 
				
			||||||
0x30,
 | 
					 | 
				
			||||||
0x30,
 | 
					 | 
				
			||||||
0x30,
 | 
					 | 
				
			||||||
0x34,
 | 
					 | 
				
			||||||
0x0,
 | 
					 | 
				
			||||||
0x8,
 | 
					0x8,
 | 
				
			||||||
0x5f,
 | 
					0x5f,
 | 
				
			||||||
0x43,
 | 
					0x43,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x53,
 | 
					0x53,
 | 
				
			||||||
0x44,
 | 
					0x44,
 | 
				
			||||||
0x54,
 | 
					0x54,
 | 
				
			||||||
0xd7,
 | 
					0xd2,
 | 
				
			||||||
0x1c,
 | 
					0x1c,
 | 
				
			||||||
0x0,
 | 
					0x0,
 | 
				
			||||||
0x0,
 | 
					0x0,
 | 
				
			||||||
0x1,
 | 
					0x1,
 | 
				
			||||||
0x3e,
 | 
					0x13,
 | 
				
			||||||
0x42,
 | 
					0x42,
 | 
				
			||||||
0x58,
 | 
					0x58,
 | 
				
			||||||
0x50,
 | 
					0x50,
 | 
				
			||||||
@@ -31,8 +31,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x4e,
 | 
					0x4e,
 | 
				
			||||||
0x54,
 | 
					0x54,
 | 
				
			||||||
0x4c,
 | 
					0x4c,
 | 
				
			||||||
0x23,
 | 
					0x15,
 | 
				
			||||||
0x8,
 | 
					0x11,
 | 
				
			||||||
0x13,
 | 
					0x13,
 | 
				
			||||||
0x20,
 | 
					0x20,
 | 
				
			||||||
0x10,
 | 
					0x10,
 | 
				
			||||||
@@ -6959,7 +6959,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x53,
 | 
					0x53,
 | 
				
			||||||
0x1,
 | 
					0x1,
 | 
				
			||||||
0x10,
 | 
					0x10,
 | 
				
			||||||
0x47,
 | 
					0x42,
 | 
				
			||||||
0x11,
 | 
					0x11,
 | 
				
			||||||
0x5f,
 | 
					0x5f,
 | 
				
			||||||
0x53,
 | 
					0x53,
 | 
				
			||||||
@@ -7192,7 +7192,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x60,
 | 
					0x60,
 | 
				
			||||||
0x5b,
 | 
					0x5b,
 | 
				
			||||||
0x82,
 | 
					0x82,
 | 
				
			||||||
0x2e,
 | 
					0x29,
 | 
				
			||||||
0x50,
 | 
					0x50,
 | 
				
			||||||
0x52,
 | 
					0x52,
 | 
				
			||||||
0x45,
 | 
					0x45,
 | 
				
			||||||
@@ -7202,16 +7202,11 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 | 
				
			|||||||
0x48,
 | 
					0x48,
 | 
				
			||||||
0x49,
 | 
					0x49,
 | 
				
			||||||
0x44,
 | 
					0x44,
 | 
				
			||||||
0xd,
 | 
					0xc,
 | 
				
			||||||
0x41,
 | 
					0x41,
 | 
				
			||||||
0x43,
 | 
					0xd0,
 | 
				
			||||||
0x50,
 | 
					0xa,
 | 
				
			||||||
0x49,
 | 
					0x6,
 | 
				
			||||||
0x30,
 | 
					 | 
				
			||||||
0x30,
 | 
					 | 
				
			||||||
0x30,
 | 
					 | 
				
			||||||
0x34,
 | 
					 | 
				
			||||||
0x0,
 | 
					 | 
				
			||||||
0x8,
 | 
					0x8,
 | 
				
			||||||
0x5f,
 | 
					0x5f,
 | 
				
			||||||
0x43,
 | 
					0x43,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1602,7 +1602,7 @@ static bool cmd_smart(IDEState *s, uint8_t cmd)
 | 
				
			|||||||
        case 2: /* extended self test */
 | 
					        case 2: /* extended self test */
 | 
				
			||||||
            s->smart_selftest_count++;
 | 
					            s->smart_selftest_count++;
 | 
				
			||||||
            if (s->smart_selftest_count > 21) {
 | 
					            if (s->smart_selftest_count > 21) {
 | 
				
			||||||
                s->smart_selftest_count = 0;
 | 
					                s->smart_selftest_count = 1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            n = 2 + (s->smart_selftest_count - 1) * 24;
 | 
					            n = 2 + (s->smart_selftest_count - 1) * 24;
 | 
				
			||||||
            s->smart_selftest_data[n] = s->sector;
 | 
					            s->smart_selftest_data[n] = s->sector;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,11 +23,20 @@
 | 
				
			|||||||
static void aw_a10_pic_update(AwA10PICState *s)
 | 
					static void aw_a10_pic_update(AwA10PICState *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint8_t i;
 | 
					    uint8_t i;
 | 
				
			||||||
    int irq = 0, fiq = 0;
 | 
					    int irq = 0, fiq = 0, pending;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->vector = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < AW_A10_PIC_REG_NUM; i++) {
 | 
					    for (i = 0; i < AW_A10_PIC_REG_NUM; i++) {
 | 
				
			||||||
        irq |= s->irq_pending[i] & ~s->mask[i];
 | 
					        irq |= s->irq_pending[i] & ~s->mask[i];
 | 
				
			||||||
        fiq |= s->select[i] & s->irq_pending[i] & ~s->mask[i];
 | 
					        fiq |= s->select[i] & s->irq_pending[i] & ~s->mask[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!s->vector) {
 | 
				
			||||||
 | 
					            pending = ffs(s->irq_pending[i] & ~s->mask[i]);
 | 
				
			||||||
 | 
					            if (pending) {
 | 
				
			||||||
 | 
					                s->vector = (i * 32 + pending - 1) * 4;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_set_irq(s->parent_irq, !!irq);
 | 
					    qemu_set_irq(s->parent_irq, !!irq);
 | 
				
			||||||
@@ -40,6 +49,8 @@ static void aw_a10_pic_set_irq(void *opaque, int irq, int level)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (level) {
 | 
					    if (level) {
 | 
				
			||||||
        set_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
 | 
					        set_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        clear_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    aw_a10_pic_update(s);
 | 
					    aw_a10_pic_update(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -84,9 +95,6 @@ static void aw_a10_pic_write(void *opaque, hwaddr offset, uint64_t value,
 | 
				
			|||||||
    uint8_t index = (offset & 0xc) / 4;
 | 
					    uint8_t index = (offset & 0xc) / 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (offset) {
 | 
					    switch (offset) {
 | 
				
			||||||
    case AW_A10_PIC_VECTOR:
 | 
					 | 
				
			||||||
        s->vector = value & ~0x3;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case AW_A10_PIC_BASE_ADDR:
 | 
					    case AW_A10_PIC_BASE_ADDR:
 | 
				
			||||||
        s->base_addr = value & ~0x3;
 | 
					        s->base_addr = value & ~0x3;
 | 
				
			||||||
    case AW_A10_PIC_PROTECT:
 | 
					    case AW_A10_PIC_PROTECT:
 | 
				
			||||||
@@ -96,7 +104,11 @@ static void aw_a10_pic_write(void *opaque, hwaddr offset, uint64_t value,
 | 
				
			|||||||
        s->nmi = value;
 | 
					        s->nmi = value;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case AW_A10_PIC_IRQ_PENDING ... AW_A10_PIC_IRQ_PENDING + 8:
 | 
					    case AW_A10_PIC_IRQ_PENDING ... AW_A10_PIC_IRQ_PENDING + 8:
 | 
				
			||||||
        s->irq_pending[index] &= ~value;
 | 
					        /*
 | 
				
			||||||
 | 
					         * The register is read-only; nevertheless, Linux (including
 | 
				
			||||||
 | 
					         * the version originally shipped by Allwinner) pretends to
 | 
				
			||||||
 | 
					         * write to the register. Just ignore it.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case AW_A10_PIC_FIQ_PENDING ... AW_A10_PIC_FIQ_PENDING + 8:
 | 
					    case AW_A10_PIC_FIQ_PENDING ... AW_A10_PIC_FIQ_PENDING + 8:
 | 
				
			||||||
        s->fiq_pending[index] &= ~value;
 | 
					        s->fiq_pending[index] &= ~value;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,102 +19,155 @@
 | 
				
			|||||||
#include "hw/sysbus.h"
 | 
					#include "hw/sysbus.h"
 | 
				
			||||||
#include "sysemu/sysemu.h"
 | 
					#include "sysemu/sysemu.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ZYNQ_ARM_SLCR_ERR_DEBUG
 | 
					#ifndef ZYNQ_SLCR_ERR_DEBUG
 | 
				
			||||||
#define DB_PRINT(...) do { \
 | 
					#define ZYNQ_SLCR_ERR_DEBUG 0
 | 
				
			||||||
    fprintf(stderr,  ": %s: ", __func__); \
 | 
					 | 
				
			||||||
    fprintf(stderr, ## __VA_ARGS__); \
 | 
					 | 
				
			||||||
    } while (0);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    #define DB_PRINT(...)
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DB_PRINT(...) do { \
 | 
				
			||||||
 | 
					        if (ZYNQ_SLCR_ERR_DEBUG) { \
 | 
				
			||||||
 | 
					            fprintf(stderr,  ": %s: ", __func__); \
 | 
				
			||||||
 | 
					            fprintf(stderr, ## __VA_ARGS__); \
 | 
				
			||||||
 | 
					        } \
 | 
				
			||||||
 | 
					    } while (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define XILINX_LOCK_KEY 0x767b
 | 
					#define XILINX_LOCK_KEY 0x767b
 | 
				
			||||||
#define XILINX_UNLOCK_KEY 0xdf0d
 | 
					#define XILINX_UNLOCK_KEY 0xdf0d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define R_PSS_RST_CTRL_SOFT_RST 0x1
 | 
					#define R_PSS_RST_CTRL_SOFT_RST 0x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					enum {
 | 
				
			||||||
  ARM_PLL_CTRL,
 | 
					    SCL             = 0x000 / 4,
 | 
				
			||||||
  DDR_PLL_CTRL,
 | 
					    LOCK,
 | 
				
			||||||
  IO_PLL_CTRL,
 | 
					    UNLOCK,
 | 
				
			||||||
  PLL_STATUS,
 | 
					    LOCKSTA,
 | 
				
			||||||
  ARM_PPL_CFG,
 | 
					 | 
				
			||||||
  DDR_PLL_CFG,
 | 
					 | 
				
			||||||
  IO_PLL_CFG,
 | 
					 | 
				
			||||||
  PLL_BG_CTRL,
 | 
					 | 
				
			||||||
  PLL_MAX
 | 
					 | 
				
			||||||
} PLLValues;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					    ARM_PLL_CTRL    = 0x100 / 4,
 | 
				
			||||||
  ARM_CLK_CTRL,
 | 
					    DDR_PLL_CTRL,
 | 
				
			||||||
  DDR_CLK_CTRL,
 | 
					    IO_PLL_CTRL,
 | 
				
			||||||
  DCI_CLK_CTRL,
 | 
					    PLL_STATUS,
 | 
				
			||||||
  APER_CLK_CTRL,
 | 
					    ARM_PLL_CFG,
 | 
				
			||||||
  USB0_CLK_CTRL,
 | 
					    DDR_PLL_CFG,
 | 
				
			||||||
  USB1_CLK_CTRL,
 | 
					    IO_PLL_CFG,
 | 
				
			||||||
  GEM0_RCLK_CTRL,
 | 
					 | 
				
			||||||
  GEM1_RCLK_CTRL,
 | 
					 | 
				
			||||||
  GEM0_CLK_CTRL,
 | 
					 | 
				
			||||||
  GEM1_CLK_CTRL,
 | 
					 | 
				
			||||||
  SMC_CLK_CTRL,
 | 
					 | 
				
			||||||
  LQSPI_CLK_CTRL,
 | 
					 | 
				
			||||||
  SDIO_CLK_CTRL,
 | 
					 | 
				
			||||||
  UART_CLK_CTRL,
 | 
					 | 
				
			||||||
  SPI_CLK_CTRL,
 | 
					 | 
				
			||||||
  CAN_CLK_CTRL,
 | 
					 | 
				
			||||||
  CAN_MIOCLK_CTRL,
 | 
					 | 
				
			||||||
  DBG_CLK_CTRL,
 | 
					 | 
				
			||||||
  PCAP_CLK_CTRL,
 | 
					 | 
				
			||||||
  TOPSW_CLK_CTRL,
 | 
					 | 
				
			||||||
  CLK_MAX
 | 
					 | 
				
			||||||
} ClkValues;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					    ARM_CLK_CTRL    = 0x120 / 4,
 | 
				
			||||||
  CLK_CTRL,
 | 
					    DDR_CLK_CTRL,
 | 
				
			||||||
  THR_CTRL,
 | 
					    DCI_CLK_CTRL,
 | 
				
			||||||
  THR_CNT,
 | 
					    APER_CLK_CTRL,
 | 
				
			||||||
  THR_STA,
 | 
					    USB0_CLK_CTRL,
 | 
				
			||||||
  FPGA_MAX
 | 
					    USB1_CLK_CTRL,
 | 
				
			||||||
} FPGAValues;
 | 
					    GEM0_RCLK_CTRL,
 | 
				
			||||||
 | 
					    GEM1_RCLK_CTRL,
 | 
				
			||||||
 | 
					    GEM0_CLK_CTRL,
 | 
				
			||||||
 | 
					    GEM1_CLK_CTRL,
 | 
				
			||||||
 | 
					    SMC_CLK_CTRL,
 | 
				
			||||||
 | 
					    LQSPI_CLK_CTRL,
 | 
				
			||||||
 | 
					    SDIO_CLK_CTRL,
 | 
				
			||||||
 | 
					    UART_CLK_CTRL,
 | 
				
			||||||
 | 
					    SPI_CLK_CTRL,
 | 
				
			||||||
 | 
					    CAN_CLK_CTRL,
 | 
				
			||||||
 | 
					    CAN_MIOCLK_CTRL,
 | 
				
			||||||
 | 
					    DBG_CLK_CTRL,
 | 
				
			||||||
 | 
					    PCAP_CLK_CTRL,
 | 
				
			||||||
 | 
					    TOPSW_CLK_CTRL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					#define FPGA_CTRL_REGS(n, start) \
 | 
				
			||||||
  SYNC_CTRL,
 | 
					    FPGA ## n ## _CLK_CTRL = (start) / 4, \
 | 
				
			||||||
  SYNC_STATUS,
 | 
					    FPGA ## n ## _THR_CTRL, \
 | 
				
			||||||
  BANDGAP_TRIP,
 | 
					    FPGA ## n ## _THR_CNT, \
 | 
				
			||||||
  CC_TEST,
 | 
					    FPGA ## n ## _THR_STA,
 | 
				
			||||||
  PLL_PREDIVISOR,
 | 
					    FPGA_CTRL_REGS(0, 0x170)
 | 
				
			||||||
  CLK_621_TRUE,
 | 
					    FPGA_CTRL_REGS(1, 0x180)
 | 
				
			||||||
  PICTURE_DBG,
 | 
					    FPGA_CTRL_REGS(2, 0x190)
 | 
				
			||||||
  PICTURE_DBG_UCNT,
 | 
					    FPGA_CTRL_REGS(3, 0x1a0)
 | 
				
			||||||
  PICTURE_DBG_LCNT,
 | 
					 | 
				
			||||||
  MISC_MAX
 | 
					 | 
				
			||||||
} MiscValues;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					    BANDGAP_TRIP    = 0x1b8 / 4,
 | 
				
			||||||
  PSS,
 | 
					    PLL_PREDIVISOR  = 0x1c0 / 4,
 | 
				
			||||||
  DDDR,
 | 
					    CLK_621_TRUE,
 | 
				
			||||||
  DMAC = 3,
 | 
					
 | 
				
			||||||
  USB,
 | 
					    PSS_RST_CTRL    = 0x200 / 4,
 | 
				
			||||||
  GEM,
 | 
					    DDR_RST_CTRL,
 | 
				
			||||||
  SDIO,
 | 
					    TOPSW_RESET_CTRL,
 | 
				
			||||||
  SPI,
 | 
					    DMAC_RST_CTRL,
 | 
				
			||||||
  CAN,
 | 
					    USB_RST_CTRL,
 | 
				
			||||||
  I2C,
 | 
					    GEM_RST_CTRL,
 | 
				
			||||||
  UART,
 | 
					    SDIO_RST_CTRL,
 | 
				
			||||||
  GPIO,
 | 
					    SPI_RST_CTRL,
 | 
				
			||||||
  LQSPI,
 | 
					    CAN_RST_CTRL,
 | 
				
			||||||
  SMC,
 | 
					    I2C_RST_CTRL,
 | 
				
			||||||
  OCM,
 | 
					    UART_RST_CTRL,
 | 
				
			||||||
  DEVCI,
 | 
					    GPIO_RST_CTRL,
 | 
				
			||||||
  FPGA,
 | 
					    LQSPI_RST_CTRL,
 | 
				
			||||||
  A9_CPU,
 | 
					    SMC_RST_CTRL,
 | 
				
			||||||
  RS_AWDT,
 | 
					    OCM_RST_CTRL,
 | 
				
			||||||
  RST_REASON,
 | 
					    FPGA_RST_CTRL   = 0x240 / 4,
 | 
				
			||||||
  RST_REASON_CLR,
 | 
					    A9_CPU_RST_CTRL,
 | 
				
			||||||
  REBOOT_STATUS,
 | 
					
 | 
				
			||||||
  BOOT_MODE,
 | 
					    RS_AWDT_CTRL    = 0x24c / 4,
 | 
				
			||||||
  RESET_MAX
 | 
					    RST_REASON,
 | 
				
			||||||
} ResetValues;
 | 
					
 | 
				
			||||||
 | 
					    REBOOT_STATUS   = 0x258 / 4,
 | 
				
			||||||
 | 
					    BOOT_MODE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    APU_CTRL        = 0x300 / 4,
 | 
				
			||||||
 | 
					    WDT_CLK_SEL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TZ_DMA_NS       = 0x440 / 4,
 | 
				
			||||||
 | 
					    TZ_DMA_IRQ_NS,
 | 
				
			||||||
 | 
					    TZ_DMA_PERIPH_NS,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PSS_IDCODE      = 0x530 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DDR_URGENT      = 0x600 / 4,
 | 
				
			||||||
 | 
					    DDR_CAL_START   = 0x60c / 4,
 | 
				
			||||||
 | 
					    DDR_REF_START   = 0x614 / 4,
 | 
				
			||||||
 | 
					    DDR_CMD_STA,
 | 
				
			||||||
 | 
					    DDR_URGENT_SEL,
 | 
				
			||||||
 | 
					    DDR_DFI_STATUS,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MIO             = 0x700 / 4,
 | 
				
			||||||
 | 
					#define MIO_LENGTH 54
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MIO_LOOPBACK    = 0x804 / 4,
 | 
				
			||||||
 | 
					    MIO_MST_TRI0,
 | 
				
			||||||
 | 
					    MIO_MST_TRI1,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SD0_WP_CD_SEL   = 0x830 / 4,
 | 
				
			||||||
 | 
					    SD1_WP_CD_SEL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LVL_SHFTR_EN    = 0x900 / 4,
 | 
				
			||||||
 | 
					    OCM_CFG         = 0x910 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CPU_RAM         = 0xa00 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IOU             = 0xa30 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DMAC_RAM        = 0xa50 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AFI0            = 0xa60 / 4,
 | 
				
			||||||
 | 
					    AFI1 = AFI0 + 3,
 | 
				
			||||||
 | 
					    AFI2 = AFI1 + 3,
 | 
				
			||||||
 | 
					    AFI3 = AFI2 + 3,
 | 
				
			||||||
 | 
					#define AFI_LENGTH 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OCM             = 0xa90 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEVCI_RAM       = 0xaa0 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CSG_RAM         = 0xab0 / 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPIOB_CTRL      = 0xb00 / 4,
 | 
				
			||||||
 | 
					    GPIOB_CFG_CMOS18,
 | 
				
			||||||
 | 
					    GPIOB_CFG_CMOS25,
 | 
				
			||||||
 | 
					    GPIOB_CFG_CMOS33,
 | 
				
			||||||
 | 
					    GPIOB_CFG_HSTL  = 0xb14 / 4,
 | 
				
			||||||
 | 
					    GPIOB_DRVR_BIAS_CTRL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DDRIOB          = 0xb40 / 4,
 | 
				
			||||||
 | 
					#define DDRIOB_LENGTH 14
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ZYNQ_SLCR_MMIO_SIZE     0x1000
 | 
				
			||||||
 | 
					#define ZYNQ_SLCR_NUM_REGS      (ZYNQ_SLCR_MMIO_SIZE / 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TYPE_ZYNQ_SLCR "xilinx,zynq_slcr"
 | 
					#define TYPE_ZYNQ_SLCR "xilinx,zynq_slcr"
 | 
				
			||||||
#define ZYNQ_SLCR(obj) OBJECT_CHECK(ZynqSLCRState, (obj), TYPE_ZYNQ_SLCR)
 | 
					#define ZYNQ_SLCR(obj) OBJECT_CHECK(ZynqSLCRState, (obj), TYPE_ZYNQ_SLCR)
 | 
				
			||||||
@@ -124,42 +177,7 @@ typedef struct ZynqSLCRState {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    MemoryRegion iomem;
 | 
					    MemoryRegion iomem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    union {
 | 
					    uint32_t regs[ZYNQ_SLCR_NUM_REGS];
 | 
				
			||||||
        struct {
 | 
					 | 
				
			||||||
            uint16_t scl;
 | 
					 | 
				
			||||||
            uint16_t lockval;
 | 
					 | 
				
			||||||
            uint32_t pll[PLL_MAX]; /* 0x100 - 0x11C */
 | 
					 | 
				
			||||||
            uint32_t clk[CLK_MAX]; /* 0x120 - 0x16C */
 | 
					 | 
				
			||||||
            uint32_t fpga[4][FPGA_MAX]; /* 0x170 - 0x1AC */
 | 
					 | 
				
			||||||
            uint32_t misc[MISC_MAX]; /* 0x1B0 - 0x1D8 */
 | 
					 | 
				
			||||||
            uint32_t reset[RESET_MAX]; /* 0x200 - 0x25C */
 | 
					 | 
				
			||||||
            uint32_t apu_ctrl; /* 0x300 */
 | 
					 | 
				
			||||||
            uint32_t wdt_clk_sel; /* 0x304 */
 | 
					 | 
				
			||||||
            uint32_t tz_ocm[3]; /* 0x400 - 0x408 */
 | 
					 | 
				
			||||||
            uint32_t tz_ddr; /* 0x430 */
 | 
					 | 
				
			||||||
            uint32_t tz_dma[3]; /* 0x440 - 0x448 */
 | 
					 | 
				
			||||||
            uint32_t tz_misc[3]; /* 0x450 - 0x458 */
 | 
					 | 
				
			||||||
            uint32_t tz_fpga[2]; /* 0x484 - 0x488 */
 | 
					 | 
				
			||||||
            uint32_t dbg_ctrl; /* 0x500 */
 | 
					 | 
				
			||||||
            uint32_t pss_idcode; /* 0x530 */
 | 
					 | 
				
			||||||
            uint32_t ddr[8]; /* 0x600 - 0x620 - 0x604-missing */
 | 
					 | 
				
			||||||
            uint32_t mio[54]; /* 0x700 - 0x7D4 */
 | 
					 | 
				
			||||||
            uint32_t mio_func[4]; /* 0x800 - 0x810 */
 | 
					 | 
				
			||||||
            uint32_t sd[2]; /* 0x830 - 0x834 */
 | 
					 | 
				
			||||||
            uint32_t lvl_shftr_en; /* 0x900 */
 | 
					 | 
				
			||||||
            uint32_t ocm_cfg; /* 0x910 */
 | 
					 | 
				
			||||||
            uint32_t cpu_ram[8]; /* 0xA00 - 0xA1C */
 | 
					 | 
				
			||||||
            uint32_t iou[7]; /* 0xA30 - 0xA48 */
 | 
					 | 
				
			||||||
            uint32_t dmac_ram; /* 0xA50 */
 | 
					 | 
				
			||||||
            uint32_t afi[4][3]; /* 0xA60 - 0xA8C */
 | 
					 | 
				
			||||||
            uint32_t ocm[3]; /* 0xA90 - 0xA98 */
 | 
					 | 
				
			||||||
            uint32_t devci_ram; /* 0xAA0 */
 | 
					 | 
				
			||||||
            uint32_t csg_ram; /* 0xAB0 */
 | 
					 | 
				
			||||||
            uint32_t gpiob[12]; /* 0xB00 - 0xB2C */
 | 
					 | 
				
			||||||
            uint32_t ddriob[14]; /* 0xB40 - 0xB74 */
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        uint8_t data[0x1000];
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
} ZynqSLCRState;
 | 
					} ZynqSLCRState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void zynq_slcr_reset(DeviceState *d)
 | 
					static void zynq_slcr_reset(DeviceState *d)
 | 
				
			||||||
@@ -169,177 +187,169 @@ static void zynq_slcr_reset(DeviceState *d)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    DB_PRINT("RESET\n");
 | 
					    DB_PRINT("RESET\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->lockval = 1;
 | 
					    s->regs[LOCKSTA] = 1;
 | 
				
			||||||
    /* 0x100 - 0x11C */
 | 
					    /* 0x100 - 0x11C */
 | 
				
			||||||
    s->pll[ARM_PLL_CTRL] = 0x0001A008;
 | 
					    s->regs[ARM_PLL_CTRL]   = 0x0001A008;
 | 
				
			||||||
    s->pll[DDR_PLL_CTRL] = 0x0001A008;
 | 
					    s->regs[DDR_PLL_CTRL]   = 0x0001A008;
 | 
				
			||||||
    s->pll[IO_PLL_CTRL] = 0x0001A008;
 | 
					    s->regs[IO_PLL_CTRL]    = 0x0001A008;
 | 
				
			||||||
    s->pll[PLL_STATUS] = 0x0000003F;
 | 
					    s->regs[PLL_STATUS]     = 0x0000003F;
 | 
				
			||||||
    s->pll[ARM_PPL_CFG] = 0x00014000;
 | 
					    s->regs[ARM_PLL_CFG]    = 0x00014000;
 | 
				
			||||||
    s->pll[DDR_PLL_CFG] = 0x00014000;
 | 
					    s->regs[DDR_PLL_CFG]    = 0x00014000;
 | 
				
			||||||
    s->pll[IO_PLL_CFG] = 0x00014000;
 | 
					    s->regs[IO_PLL_CFG]     = 0x00014000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 0x120 - 0x16C */
 | 
					    /* 0x120 - 0x16C */
 | 
				
			||||||
    s->clk[ARM_CLK_CTRL] = 0x1F000400;
 | 
					    s->regs[ARM_CLK_CTRL]   = 0x1F000400;
 | 
				
			||||||
    s->clk[DDR_CLK_CTRL] = 0x18400003;
 | 
					    s->regs[DDR_CLK_CTRL]   = 0x18400003;
 | 
				
			||||||
    s->clk[DCI_CLK_CTRL] = 0x01E03201;
 | 
					    s->regs[DCI_CLK_CTRL]   = 0x01E03201;
 | 
				
			||||||
    s->clk[APER_CLK_CTRL] = 0x01FFCCCD;
 | 
					    s->regs[APER_CLK_CTRL]  = 0x01FFCCCD;
 | 
				
			||||||
    s->clk[USB0_CLK_CTRL] = s->clk[USB1_CLK_CTRL] = 0x00101941;
 | 
					    s->regs[USB0_CLK_CTRL]  = s->regs[USB1_CLK_CTRL]    = 0x00101941;
 | 
				
			||||||
    s->clk[GEM0_RCLK_CTRL] = s->clk[GEM1_RCLK_CTRL] = 0x00000001;
 | 
					    s->regs[GEM0_RCLK_CTRL] = s->regs[GEM1_RCLK_CTRL]   = 0x00000001;
 | 
				
			||||||
    s->clk[GEM0_CLK_CTRL] = s->clk[GEM1_CLK_CTRL] = 0x00003C01;
 | 
					    s->regs[GEM0_CLK_CTRL]  = s->regs[GEM1_CLK_CTRL]    = 0x00003C01;
 | 
				
			||||||
    s->clk[SMC_CLK_CTRL] = 0x00003C01;
 | 
					    s->regs[SMC_CLK_CTRL]   = 0x00003C01;
 | 
				
			||||||
    s->clk[LQSPI_CLK_CTRL] = 0x00002821;
 | 
					    s->regs[LQSPI_CLK_CTRL] = 0x00002821;
 | 
				
			||||||
    s->clk[SDIO_CLK_CTRL] = 0x00001E03;
 | 
					    s->regs[SDIO_CLK_CTRL]  = 0x00001E03;
 | 
				
			||||||
    s->clk[UART_CLK_CTRL] = 0x00003F03;
 | 
					    s->regs[UART_CLK_CTRL]  = 0x00003F03;
 | 
				
			||||||
    s->clk[SPI_CLK_CTRL] = 0x00003F03;
 | 
					    s->regs[SPI_CLK_CTRL]   = 0x00003F03;
 | 
				
			||||||
    s->clk[CAN_CLK_CTRL] = 0x00501903;
 | 
					    s->regs[CAN_CLK_CTRL]   = 0x00501903;
 | 
				
			||||||
    s->clk[DBG_CLK_CTRL] = 0x00000F03;
 | 
					    s->regs[DBG_CLK_CTRL]   = 0x00000F03;
 | 
				
			||||||
    s->clk[PCAP_CLK_CTRL] = 0x00000F01;
 | 
					    s->regs[PCAP_CLK_CTRL]  = 0x00000F01;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 0x170 - 0x1AC */
 | 
					    /* 0x170 - 0x1AC */
 | 
				
			||||||
    s->fpga[0][CLK_CTRL] = s->fpga[1][CLK_CTRL] = s->fpga[2][CLK_CTRL] =
 | 
					    s->regs[FPGA0_CLK_CTRL] = s->regs[FPGA1_CLK_CTRL] = s->regs[FPGA2_CLK_CTRL]
 | 
				
			||||||
            s->fpga[3][CLK_CTRL] = 0x00101800;
 | 
					                            = s->regs[FPGA3_CLK_CTRL] = 0x00101800;
 | 
				
			||||||
    s->fpga[0][THR_STA] = s->fpga[1][THR_STA] = s->fpga[2][THR_STA] =
 | 
					    s->regs[FPGA0_THR_STA] = s->regs[FPGA1_THR_STA] = s->regs[FPGA2_THR_STA]
 | 
				
			||||||
            s->fpga[3][THR_STA] = 0x00010000;
 | 
					                           = s->regs[FPGA3_THR_STA] = 0x00010000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 0x1B0 - 0x1D8 */
 | 
					    /* 0x1B0 - 0x1D8 */
 | 
				
			||||||
    s->misc[BANDGAP_TRIP] = 0x0000001F;
 | 
					    s->regs[BANDGAP_TRIP]   = 0x0000001F;
 | 
				
			||||||
    s->misc[PLL_PREDIVISOR] = 0x00000001;
 | 
					    s->regs[PLL_PREDIVISOR] = 0x00000001;
 | 
				
			||||||
    s->misc[CLK_621_TRUE] = 0x00000001;
 | 
					    s->regs[CLK_621_TRUE]   = 0x00000001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 0x200 - 0x25C */
 | 
					    /* 0x200 - 0x25C */
 | 
				
			||||||
    s->reset[FPGA] = 0x01F33F0F;
 | 
					    s->regs[FPGA_RST_CTRL]  = 0x01F33F0F;
 | 
				
			||||||
    s->reset[RST_REASON] = 0x00000040;
 | 
					    s->regs[RST_REASON]     = 0x00000040;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->regs[BOOT_MODE]      = 0x00000001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 0x700 - 0x7D4 */
 | 
					    /* 0x700 - 0x7D4 */
 | 
				
			||||||
    for (i = 0; i < 54; i++) {
 | 
					    for (i = 0; i < 54; i++) {
 | 
				
			||||||
        s->mio[i] = 0x00001601;
 | 
					        s->regs[MIO + i] = 0x00001601;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (i = 2; i <= 8; i++) {
 | 
					    for (i = 2; i <= 8; i++) {
 | 
				
			||||||
        s->mio[i] = 0x00000601;
 | 
					        s->regs[MIO + i] = 0x00000601;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* MIO_MST_TRI0, MIO_MST_TRI1 */
 | 
					    s->regs[MIO_MST_TRI0] = s->regs[MIO_MST_TRI1] = 0xFFFFFFFF;
 | 
				
			||||||
    s->mio_func[2] = s->mio_func[3] = 0xFFFFFFFF;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->cpu_ram[0] = s->cpu_ram[1] = s->cpu_ram[3] =
 | 
					    s->regs[CPU_RAM + 0] = s->regs[CPU_RAM + 1] = s->regs[CPU_RAM + 3]
 | 
				
			||||||
            s->cpu_ram[4] = s->cpu_ram[7] = 0x00010101;
 | 
					                         = s->regs[CPU_RAM + 4] = s->regs[CPU_RAM + 7]
 | 
				
			||||||
    s->cpu_ram[2] = s->cpu_ram[5] = 0x01010101;
 | 
					                         = 0x00010101;
 | 
				
			||||||
    s->cpu_ram[6] = 0x00000001;
 | 
					    s->regs[CPU_RAM + 2] = s->regs[CPU_RAM + 5] = 0x01010101;
 | 
				
			||||||
 | 
					    s->regs[CPU_RAM + 6] = 0x00000001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->iou[0] = s->iou[1] = s->iou[2] = s->iou[3] = 0x09090909;
 | 
					    s->regs[IOU + 0] = s->regs[IOU + 1] = s->regs[IOU + 2] = s->regs[IOU + 3]
 | 
				
			||||||
    s->iou[4] = s->iou[5] = 0x00090909;
 | 
					                     = 0x09090909;
 | 
				
			||||||
    s->iou[6] = 0x00000909;
 | 
					    s->regs[IOU + 4] = s->regs[IOU + 5] = 0x00090909;
 | 
				
			||||||
 | 
					    s->regs[IOU + 6] = 0x00000909;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->dmac_ram = 0x00000009;
 | 
					    s->regs[DMAC_RAM] = 0x00000009;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->afi[0][0] = s->afi[0][1] = 0x09090909;
 | 
					    s->regs[AFI0 + 0] = s->regs[AFI0 + 1] = 0x09090909;
 | 
				
			||||||
    s->afi[1][0] = s->afi[1][1] = 0x09090909;
 | 
					    s->regs[AFI1 + 0] = s->regs[AFI1 + 1] = 0x09090909;
 | 
				
			||||||
    s->afi[2][0] = s->afi[2][1] = 0x09090909;
 | 
					    s->regs[AFI2 + 0] = s->regs[AFI2 + 1] = 0x09090909;
 | 
				
			||||||
    s->afi[3][0] = s->afi[3][1] = 0x09090909;
 | 
					    s->regs[AFI3 + 0] = s->regs[AFI3 + 1] = 0x09090909;
 | 
				
			||||||
    s->afi[0][2] = s->afi[1][2] = s->afi[2][2] = s->afi[3][2] = 0x00000909;
 | 
					    s->regs[AFI0 + 2] = s->regs[AFI1 + 2] = s->regs[AFI2 + 2]
 | 
				
			||||||
 | 
					                      = s->regs[AFI3 + 2] = 0x00000909;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->ocm[0] = 0x01010101;
 | 
					    s->regs[OCM + 0]    = 0x01010101;
 | 
				
			||||||
    s->ocm[1] = s->ocm[2] = 0x09090909;
 | 
					    s->regs[OCM + 1]    = s->regs[OCM + 2] = 0x09090909;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->devci_ram = 0x00000909;
 | 
					    s->regs[DEVCI_RAM]  = 0x00000909;
 | 
				
			||||||
    s->csg_ram = 0x00000001;
 | 
					    s->regs[CSG_RAM]    = 0x00000001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->ddriob[0] = s->ddriob[1] = s->ddriob[2] = s->ddriob[3] = 0x00000e00;
 | 
					    s->regs[DDRIOB + 0] = s->regs[DDRIOB + 1] = s->regs[DDRIOB + 2]
 | 
				
			||||||
    s->ddriob[4] = s->ddriob[5] = s->ddriob[6] = 0x00000e00;
 | 
					                        = s->regs[DDRIOB + 3] = 0x00000e00;
 | 
				
			||||||
    s->ddriob[12] = 0x00000021;
 | 
					    s->regs[DDRIOB + 4] = s->regs[DDRIOB + 5] = s->regs[DDRIOB + 6]
 | 
				
			||||||
 | 
					                        = 0x00000e00;
 | 
				
			||||||
 | 
					    s->regs[DDRIOB + 12] = 0x00000021;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline uint32_t zynq_slcr_read_imp(void *opaque,
 | 
					 | 
				
			||||||
    hwaddr offset)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ZynqSLCRState *s = (ZynqSLCRState *)opaque;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool zynq_slcr_check_offset(hwaddr offset, bool rnw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    switch (offset) {
 | 
					    switch (offset) {
 | 
				
			||||||
    case 0x0: /* SCL */
 | 
					    case LOCK:
 | 
				
			||||||
        return s->scl;
 | 
					    case UNLOCK:
 | 
				
			||||||
    case 0x4: /* LOCK */
 | 
					    case DDR_CAL_START:
 | 
				
			||||||
    case 0x8: /* UNLOCK */
 | 
					    case DDR_REF_START:
 | 
				
			||||||
        DB_PRINT("Reading SCLR_LOCK/UNLOCK is not enabled\n");
 | 
					        return !rnw; /* Write only */
 | 
				
			||||||
        return 0;
 | 
					    case LOCKSTA:
 | 
				
			||||||
    case 0x0C: /* LOCKSTA */
 | 
					    case FPGA0_THR_STA:
 | 
				
			||||||
        return s->lockval;
 | 
					    case FPGA1_THR_STA:
 | 
				
			||||||
    case 0x100 ... 0x11C:
 | 
					    case FPGA2_THR_STA:
 | 
				
			||||||
        return s->pll[(offset - 0x100) / 4];
 | 
					    case FPGA3_THR_STA:
 | 
				
			||||||
    case 0x120 ... 0x16C:
 | 
					    case BOOT_MODE:
 | 
				
			||||||
        return s->clk[(offset - 0x120) / 4];
 | 
					    case PSS_IDCODE:
 | 
				
			||||||
    case 0x170 ... 0x1AC:
 | 
					    case DDR_CMD_STA:
 | 
				
			||||||
        return s->fpga[0][(offset - 0x170) / 4];
 | 
					    case DDR_DFI_STATUS:
 | 
				
			||||||
    case 0x1B0 ... 0x1D8:
 | 
					    case PLL_STATUS:
 | 
				
			||||||
        return s->misc[(offset - 0x1B0) / 4];
 | 
					        return rnw;/* read only */
 | 
				
			||||||
    case 0x200 ... 0x258:
 | 
					    case SCL:
 | 
				
			||||||
        return s->reset[(offset - 0x200) / 4];
 | 
					    case ARM_PLL_CTRL ... IO_PLL_CTRL:
 | 
				
			||||||
    case 0x25c:
 | 
					    case ARM_PLL_CFG ... IO_PLL_CFG:
 | 
				
			||||||
        return 1;
 | 
					    case ARM_CLK_CTRL ... TOPSW_CLK_CTRL:
 | 
				
			||||||
    case 0x300:
 | 
					    case FPGA0_CLK_CTRL ... FPGA0_THR_CNT:
 | 
				
			||||||
        return s->apu_ctrl;
 | 
					    case FPGA1_CLK_CTRL ... FPGA1_THR_CNT:
 | 
				
			||||||
    case 0x304:
 | 
					    case FPGA2_CLK_CTRL ... FPGA2_THR_CNT:
 | 
				
			||||||
        return s->wdt_clk_sel;
 | 
					    case FPGA3_CLK_CTRL ... FPGA3_THR_CNT:
 | 
				
			||||||
    case 0x400 ... 0x408:
 | 
					    case BANDGAP_TRIP:
 | 
				
			||||||
        return s->tz_ocm[(offset - 0x400) / 4];
 | 
					    case PLL_PREDIVISOR:
 | 
				
			||||||
    case 0x430:
 | 
					    case CLK_621_TRUE:
 | 
				
			||||||
        return s->tz_ddr;
 | 
					    case PSS_RST_CTRL ... A9_CPU_RST_CTRL:
 | 
				
			||||||
    case 0x440 ... 0x448:
 | 
					    case RS_AWDT_CTRL:
 | 
				
			||||||
        return s->tz_dma[(offset - 0x440) / 4];
 | 
					    case RST_REASON:
 | 
				
			||||||
    case 0x450 ... 0x458:
 | 
					    case REBOOT_STATUS:
 | 
				
			||||||
        return s->tz_misc[(offset - 0x450) / 4];
 | 
					    case APU_CTRL:
 | 
				
			||||||
    case 0x484 ... 0x488:
 | 
					    case WDT_CLK_SEL:
 | 
				
			||||||
        return s->tz_fpga[(offset - 0x484) / 4];
 | 
					    case TZ_DMA_NS ... TZ_DMA_PERIPH_NS:
 | 
				
			||||||
    case 0x500:
 | 
					    case DDR_URGENT:
 | 
				
			||||||
        return s->dbg_ctrl;
 | 
					    case DDR_URGENT_SEL:
 | 
				
			||||||
    case 0x530:
 | 
					    case MIO ... MIO + MIO_LENGTH - 1:
 | 
				
			||||||
        return s->pss_idcode;
 | 
					    case MIO_LOOPBACK ... MIO_MST_TRI1:
 | 
				
			||||||
    case 0x600 ... 0x620:
 | 
					    case SD0_WP_CD_SEL:
 | 
				
			||||||
        if (offset == 0x604) {
 | 
					    case SD1_WP_CD_SEL:
 | 
				
			||||||
            goto bad_reg;
 | 
					    case LVL_SHFTR_EN:
 | 
				
			||||||
        }
 | 
					    case OCM_CFG:
 | 
				
			||||||
        return s->ddr[(offset - 0x600) / 4];
 | 
					    case CPU_RAM:
 | 
				
			||||||
    case 0x700 ... 0x7D4:
 | 
					    case IOU:
 | 
				
			||||||
        return s->mio[(offset - 0x700) / 4];
 | 
					    case DMAC_RAM:
 | 
				
			||||||
    case 0x800 ... 0x810:
 | 
					    case AFI0 ... AFI3 + AFI_LENGTH - 1:
 | 
				
			||||||
        return s->mio_func[(offset - 0x800) / 4];
 | 
					    case OCM:
 | 
				
			||||||
    case 0x830 ... 0x834:
 | 
					    case DEVCI_RAM:
 | 
				
			||||||
        return s->sd[(offset - 0x830) / 4];
 | 
					    case CSG_RAM:
 | 
				
			||||||
    case 0x900:
 | 
					    case GPIOB_CTRL ... GPIOB_CFG_CMOS33:
 | 
				
			||||||
        return s->lvl_shftr_en;
 | 
					    case GPIOB_CFG_HSTL:
 | 
				
			||||||
    case 0x910:
 | 
					    case GPIOB_DRVR_BIAS_CTRL:
 | 
				
			||||||
        return s->ocm_cfg;
 | 
					    case DDRIOB ... DDRIOB + DDRIOB_LENGTH - 1:
 | 
				
			||||||
    case 0xA00 ... 0xA1C:
 | 
					        return true;
 | 
				
			||||||
        return s->cpu_ram[(offset - 0xA00) / 4];
 | 
					 | 
				
			||||||
    case 0xA30 ... 0xA48:
 | 
					 | 
				
			||||||
        return s->iou[(offset - 0xA30) / 4];
 | 
					 | 
				
			||||||
    case 0xA50:
 | 
					 | 
				
			||||||
        return s->dmac_ram;
 | 
					 | 
				
			||||||
    case 0xA60 ... 0xA8C:
 | 
					 | 
				
			||||||
        return s->afi[0][(offset - 0xA60) / 4];
 | 
					 | 
				
			||||||
    case 0xA90 ... 0xA98:
 | 
					 | 
				
			||||||
        return s->ocm[(offset - 0xA90) / 4];
 | 
					 | 
				
			||||||
    case 0xAA0:
 | 
					 | 
				
			||||||
        return s->devci_ram;
 | 
					 | 
				
			||||||
    case 0xAB0:
 | 
					 | 
				
			||||||
        return s->csg_ram;
 | 
					 | 
				
			||||||
    case 0xB00 ... 0xB2C:
 | 
					 | 
				
			||||||
        return s->gpiob[(offset - 0xB00) / 4];
 | 
					 | 
				
			||||||
    case 0xB40 ... 0xB74:
 | 
					 | 
				
			||||||
        return s->ddriob[(offset - 0xB40) / 4];
 | 
					 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
    bad_reg:
 | 
					        return false;
 | 
				
			||||||
        DB_PRINT("Bad register offset 0x%x\n", (int)offset);
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint64_t zynq_slcr_read(void *opaque, hwaddr offset,
 | 
					static uint64_t zynq_slcr_read(void *opaque, hwaddr offset,
 | 
				
			||||||
    unsigned size)
 | 
					    unsigned size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t ret = zynq_slcr_read_imp(opaque, offset);
 | 
					    ZynqSLCRState *s = opaque;
 | 
				
			||||||
 | 
					    offset /= 4;
 | 
				
			||||||
 | 
					    uint32_t ret = s->regs[offset];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, (unsigned)ret);
 | 
					    if (!zynq_slcr_check_offset(offset, true)) {
 | 
				
			||||||
 | 
					        qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid read access to "
 | 
				
			||||||
 | 
					                      " addr %" HWADDR_PRIx "\n", offset * 4);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset * 4, ret);
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -347,148 +357,55 @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
 | 
				
			|||||||
                          uint64_t val, unsigned size)
 | 
					                          uint64_t val, unsigned size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ZynqSLCRState *s = (ZynqSLCRState *)opaque;
 | 
					    ZynqSLCRState *s = (ZynqSLCRState *)opaque;
 | 
				
			||||||
 | 
					    offset /= 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DB_PRINT("offset: %08x data: %08x\n", (unsigned)offset, (unsigned)val);
 | 
					    DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx64 "\n", offset * 4, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!zynq_slcr_check_offset(offset, false)) {
 | 
				
			||||||
 | 
					        qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid write access to "
 | 
				
			||||||
 | 
					                      "addr %" HWADDR_PRIx "\n", offset * 4);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (offset) {
 | 
					    switch (offset) {
 | 
				
			||||||
    case 0x00: /* SCL */
 | 
					    case SCL:
 | 
				
			||||||
        s->scl = val & 0x1;
 | 
					        s->regs[SCL] = val & 0x1;
 | 
				
			||||||
    return;
 | 
					        return;
 | 
				
			||||||
    case 0x4: /* SLCR_LOCK */
 | 
					    case LOCK:
 | 
				
			||||||
        if ((val & 0xFFFF) == XILINX_LOCK_KEY) {
 | 
					        if ((val & 0xFFFF) == XILINX_LOCK_KEY) {
 | 
				
			||||||
            DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
 | 
					            DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
 | 
				
			||||||
                (unsigned)val & 0xFFFF);
 | 
					                (unsigned)val & 0xFFFF);
 | 
				
			||||||
            s->lockval = 1;
 | 
					            s->regs[LOCKSTA] = 1;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
 | 
					            DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
 | 
				
			||||||
                (int)offset, (unsigned)val & 0xFFFF);
 | 
					                (int)offset, (unsigned)val & 0xFFFF);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    case 0x8: /* SLCR_UNLOCK */
 | 
					    case UNLOCK:
 | 
				
			||||||
        if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) {
 | 
					        if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) {
 | 
				
			||||||
            DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
 | 
					            DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
 | 
				
			||||||
                (unsigned)val & 0xFFFF);
 | 
					                (unsigned)val & 0xFFFF);
 | 
				
			||||||
            s->lockval = 0;
 | 
					            s->regs[LOCKSTA] = 0;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
 | 
					            DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
 | 
				
			||||||
                (int)offset, (unsigned)val & 0xFFFF);
 | 
					                (int)offset, (unsigned)val & 0xFFFF);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    case 0xc: /* LOCKSTA */
 | 
					    }
 | 
				
			||||||
        DB_PRINT("Writing SCLR_LOCKSTA is not enabled\n");
 | 
					
 | 
				
			||||||
 | 
					    if (!s->regs[LOCKSTA]) {
 | 
				
			||||||
 | 
					        s->regs[offset / 4] = val;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        DB_PRINT("SCLR registers are locked. Unlock them first\n");
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s->lockval) {
 | 
					    switch (offset) {
 | 
				
			||||||
        switch (offset) {
 | 
					    case PSS_RST_CTRL:
 | 
				
			||||||
        case 0x100 ... 0x11C:
 | 
					        if (val & R_PSS_RST_CTRL_SOFT_RST) {
 | 
				
			||||||
            if (offset == 0x10C) {
 | 
					            qemu_system_reset_request();
 | 
				
			||||||
                goto bad_reg;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s->pll[(offset - 0x100) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x120 ... 0x16C:
 | 
					 | 
				
			||||||
            s->clk[(offset - 0x120) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x170 ... 0x1AC:
 | 
					 | 
				
			||||||
            s->fpga[0][(offset - 0x170) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x1B0 ... 0x1D8:
 | 
					 | 
				
			||||||
            s->misc[(offset - 0x1B0) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x200 ... 0x25C:
 | 
					 | 
				
			||||||
            if (offset == 0x250) {
 | 
					 | 
				
			||||||
                goto bad_reg;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s->reset[(offset - 0x200) / 4] = val;
 | 
					 | 
				
			||||||
            if (offset == 0x200 && (val & R_PSS_RST_CTRL_SOFT_RST)) {
 | 
					 | 
				
			||||||
                qemu_system_reset_request();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x300:
 | 
					 | 
				
			||||||
            s->apu_ctrl = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x304:
 | 
					 | 
				
			||||||
            s->wdt_clk_sel = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x400 ... 0x408:
 | 
					 | 
				
			||||||
            s->tz_ocm[(offset - 0x400) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x430:
 | 
					 | 
				
			||||||
            s->tz_ddr = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x440 ... 0x448:
 | 
					 | 
				
			||||||
            s->tz_dma[(offset - 0x440) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x450 ... 0x458:
 | 
					 | 
				
			||||||
            s->tz_misc[(offset - 0x450) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x484 ... 0x488:
 | 
					 | 
				
			||||||
            s->tz_fpga[(offset - 0x484) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x500:
 | 
					 | 
				
			||||||
            s->dbg_ctrl = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x530:
 | 
					 | 
				
			||||||
            s->pss_idcode = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x600 ... 0x620:
 | 
					 | 
				
			||||||
            if (offset == 0x604) {
 | 
					 | 
				
			||||||
                goto bad_reg;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s->ddr[(offset - 0x600) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x700 ... 0x7D4:
 | 
					 | 
				
			||||||
            s->mio[(offset - 0x700) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x800 ... 0x810:
 | 
					 | 
				
			||||||
            s->mio_func[(offset - 0x800) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x830 ... 0x834:
 | 
					 | 
				
			||||||
            s->sd[(offset - 0x830) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x900:
 | 
					 | 
				
			||||||
            s->lvl_shftr_en = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x910:
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xA00 ... 0xA1C:
 | 
					 | 
				
			||||||
            s->cpu_ram[(offset - 0xA00) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xA30 ... 0xA48:
 | 
					 | 
				
			||||||
            s->iou[(offset - 0xA30) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xA50:
 | 
					 | 
				
			||||||
            s->dmac_ram = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xA60 ... 0xA8C:
 | 
					 | 
				
			||||||
            s->afi[0][(offset - 0xA60) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xA90:
 | 
					 | 
				
			||||||
            s->ocm[0] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xAA0:
 | 
					 | 
				
			||||||
            s->devci_ram = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xAB0:
 | 
					 | 
				
			||||||
            s->csg_ram = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xB00 ... 0xB2C:
 | 
					 | 
				
			||||||
            if (offset == 0xB20 || offset == 0xB2C) {
 | 
					 | 
				
			||||||
                goto bad_reg;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s->gpiob[(offset - 0xB00) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xB40 ... 0xB74:
 | 
					 | 
				
			||||||
            s->ddriob[(offset - 0xB40) / 4] = val;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
        bad_reg:
 | 
					 | 
				
			||||||
            DB_PRINT("Bad register write %x <= %08x\n", (int)offset,
 | 
					 | 
				
			||||||
                     (unsigned)val);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					        break;
 | 
				
			||||||
        DB_PRINT("SCLR registers are locked. Unlock them first\n");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -498,23 +415,22 @@ static const MemoryRegionOps slcr_ops = {
 | 
				
			|||||||
    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
					    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int zynq_slcr_init(SysBusDevice *dev)
 | 
					static void zynq_slcr_init(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ZynqSLCRState *s = ZYNQ_SLCR(dev);
 | 
					    ZynqSLCRState *s = ZYNQ_SLCR(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memory_region_init_io(&s->iomem, OBJECT(s), &slcr_ops, s, "slcr", 0x1000);
 | 
					    memory_region_init_io(&s->iomem, obj, &slcr_ops, s, "slcr",
 | 
				
			||||||
    sysbus_init_mmio(dev, &s->iomem);
 | 
					                          ZYNQ_SLCR_MMIO_SIZE);
 | 
				
			||||||
 | 
					    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const VMStateDescription vmstate_zynq_slcr = {
 | 
					static const VMStateDescription vmstate_zynq_slcr = {
 | 
				
			||||||
    .name = "zynq_slcr",
 | 
					    .name = "zynq_slcr",
 | 
				
			||||||
    .version_id = 1,
 | 
					    .version_id = 2,
 | 
				
			||||||
    .minimum_version_id = 1,
 | 
					    .minimum_version_id = 2,
 | 
				
			||||||
    .minimum_version_id_old = 1,
 | 
					    .minimum_version_id_old = 2,
 | 
				
			||||||
    .fields      = (VMStateField[]) {
 | 
					    .fields      = (VMStateField[]) {
 | 
				
			||||||
        VMSTATE_UINT8_ARRAY(data, ZynqSLCRState, 0x1000),
 | 
					        VMSTATE_UINT32_ARRAY(regs, ZynqSLCRState, ZYNQ_SLCR_NUM_REGS),
 | 
				
			||||||
        VMSTATE_END_OF_LIST()
 | 
					        VMSTATE_END_OF_LIST()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -522,9 +438,7 @@ static const VMStateDescription vmstate_zynq_slcr = {
 | 
				
			|||||||
static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 | 
					static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
					    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
				
			||||||
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sdc->init = zynq_slcr_init;
 | 
					 | 
				
			||||||
    dc->vmsd = &vmstate_zynq_slcr;
 | 
					    dc->vmsd = &vmstate_zynq_slcr;
 | 
				
			||||||
    dc->reset = zynq_slcr_reset;
 | 
					    dc->reset = zynq_slcr_reset;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -534,6 +448,7 @@ static const TypeInfo zynq_slcr_info = {
 | 
				
			|||||||
    .name  = TYPE_ZYNQ_SLCR,
 | 
					    .name  = TYPE_ZYNQ_SLCR,
 | 
				
			||||||
    .parent = TYPE_SYS_BUS_DEVICE,
 | 
					    .parent = TYPE_SYS_BUS_DEVICE,
 | 
				
			||||||
    .instance_size  = sizeof(ZynqSLCRState),
 | 
					    .instance_size  = sizeof(ZynqSLCRState),
 | 
				
			||||||
 | 
					    .instance_init = zynq_slcr_init,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void zynq_slcr_register_types(void)
 | 
					static void zynq_slcr_register_types(void)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,11 @@ static uint8_t padding[60];
 | 
				
			|||||||
static void mii_set_link(RTL8201CPState *mii, bool link_ok)
 | 
					static void mii_set_link(RTL8201CPState *mii, bool link_ok)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (link_ok) {
 | 
					    if (link_ok) {
 | 
				
			||||||
        mii->bmsr |= MII_BMSR_LINK_ST;
 | 
					        mii->bmsr |= MII_BMSR_LINK_ST | MII_BMSR_AN_COMP;
 | 
				
			||||||
        mii->anlpar |= MII_ANAR_TXFD | MII_ANAR_10FD | MII_ANAR_10 |
 | 
					        mii->anlpar |= MII_ANAR_TXFD | MII_ANAR_10FD | MII_ANAR_10 |
 | 
				
			||||||
                       MII_ANAR_CSMACD;
 | 
					                       MII_ANAR_CSMACD;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        mii->bmsr &= ~MII_BMSR_LINK_ST;
 | 
					        mii->bmsr &= ~(MII_BMSR_LINK_ST | MII_BMSR_AN_COMP);
 | 
				
			||||||
        mii->anlpar = MII_ANAR_TX;
 | 
					        mii->anlpar = MII_ANAR_TX;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -391,9 +391,11 @@ static void aw_emac_write(void *opaque, hwaddr offset, uint64_t value,
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case EMAC_INT_CTL_REG:
 | 
					    case EMAC_INT_CTL_REG:
 | 
				
			||||||
        s->int_ctl = value;
 | 
					        s->int_ctl = value;
 | 
				
			||||||
 | 
					        aw_emac_update_irq(s);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case EMAC_INT_STA_REG:
 | 
					    case EMAC_INT_STA_REG:
 | 
				
			||||||
        s->int_sta &= ~value;
 | 
					        s->int_sta &= ~value;
 | 
				
			||||||
 | 
					        aw_emac_update_irq(s);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case EMAC_MAC_MADR_REG:
 | 
					    case EMAC_MAC_MADR_REG:
 | 
				
			||||||
        s->phy_target = value;
 | 
					        s->phy_target = value;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1093,7 +1093,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
 | 
				
			|||||||
            uint32_t phy_addr, reg_num;
 | 
					            uint32_t phy_addr, reg_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            phy_addr = (retval & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
 | 
					            phy_addr = (retval & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
 | 
				
			||||||
            if (phy_addr == BOARD_PHY_ADDRESS) {
 | 
					            if (phy_addr == BOARD_PHY_ADDRESS || phy_addr == 0) {
 | 
				
			||||||
                reg_num = (retval & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
 | 
					                reg_num = (retval & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
 | 
				
			||||||
                retval &= 0xFFFF0000;
 | 
					                retval &= 0xFFFF0000;
 | 
				
			||||||
                retval |= gem_phy_read(s, reg_num);
 | 
					                retval |= gem_phy_read(s, reg_num);
 | 
				
			||||||
@@ -1193,7 +1193,7 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
 | 
				
			|||||||
            uint32_t phy_addr, reg_num;
 | 
					            uint32_t phy_addr, reg_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            phy_addr = (val & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
 | 
					            phy_addr = (val & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
 | 
				
			||||||
            if (phy_addr == BOARD_PHY_ADDRESS) {
 | 
					            if (phy_addr == BOARD_PHY_ADDRESS || phy_addr == 0) {
 | 
				
			||||||
                reg_num = (val & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
 | 
					                reg_num = (val & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
 | 
				
			||||||
                gem_phy_write(s, reg_num, val);
 | 
					                gem_phy_write(s, reg_num, val);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -677,7 +677,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
 | 
				
			|||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (in_use + mac_data.entries <= MAC_TABLE_ENTRIES) {
 | 
					    if (mac_data.entries <= MAC_TABLE_ENTRIES - in_use) {
 | 
				
			||||||
        s = iov_to_buf(iov, iov_cnt, 0, &macs[in_use * ETH_ALEN],
 | 
					        s = iov_to_buf(iov, iov_cnt, 0, &macs[in_use * ETH_ALEN],
 | 
				
			||||||
                       mac_data.entries * ETH_ALEN);
 | 
					                       mac_data.entries * ETH_ALEN);
 | 
				
			||||||
        if (s != mac_data.entries * ETH_ALEN) {
 | 
					        if (s != mac_data.entries * ETH_ALEN) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,9 @@
 | 
				
			|||||||
#define VMXNET3_DEVICE_VERSION    0x1
 | 
					#define VMXNET3_DEVICE_VERSION    0x1
 | 
				
			||||||
#define VMXNET3_DEVICE_REVISION   0x1
 | 
					#define VMXNET3_DEVICE_REVISION   0x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Number of interrupt vectors for non-MSIx modes */
 | 
				
			||||||
 | 
					#define VMXNET3_MAX_NMSIX_INTRS   (1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Macros for rings descriptors access */
 | 
					/* Macros for rings descriptors access */
 | 
				
			||||||
#define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \
 | 
					#define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \
 | 
				
			||||||
    (vmw_shmem_ld8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
 | 
					    (vmw_shmem_ld8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
 | 
				
			||||||
@@ -1305,6 +1308,51 @@ static bool vmxnet3_verify_intx(VMXNET3State *s, int intx)
 | 
				
			|||||||
           (pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1));
 | 
					           (pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int max_ints = is_msix ? VMXNET3_MAX_INTRS : VMXNET3_MAX_NMSIX_INTRS;
 | 
				
			||||||
 | 
					    if (idx >= max_ints) {
 | 
				
			||||||
 | 
					        hw_error("Bad interrupt index: %d\n", idx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void vmxnet3_validate_interrupts(VMXNET3State *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VMW_CFPRN("Verifying event interrupt index (%d)", s->event_int_idx);
 | 
				
			||||||
 | 
					    vmxnet3_validate_interrupt_idx(s->msix_used, s->event_int_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < s->txq_num; i++) {
 | 
				
			||||||
 | 
					        int idx = s->txq_descr[i].intr_idx;
 | 
				
			||||||
 | 
					        VMW_CFPRN("Verifying TX queue %d interrupt index (%d)", i, idx);
 | 
				
			||||||
 | 
					        vmxnet3_validate_interrupt_idx(s->msix_used, idx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < s->rxq_num; i++) {
 | 
				
			||||||
 | 
					        int idx = s->rxq_descr[i].intr_idx;
 | 
				
			||||||
 | 
					        VMW_CFPRN("Verifying RX queue %d interrupt index (%d)", i, idx);
 | 
				
			||||||
 | 
					        vmxnet3_validate_interrupt_idx(s->msix_used, idx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void vmxnet3_validate_queues(VMXNET3State *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    * txq_num and rxq_num are total number of queues
 | 
				
			||||||
 | 
					    * configured by guest. These numbers must not
 | 
				
			||||||
 | 
					    * exceed corresponding maximal values.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->txq_num > VMXNET3_DEVICE_MAX_TX_QUEUES) {
 | 
				
			||||||
 | 
					        hw_error("Bad TX queues number: %d\n", s->txq_num);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->rxq_num > VMXNET3_DEVICE_MAX_RX_QUEUES) {
 | 
				
			||||||
 | 
					        hw_error("Bad RX queues number: %d\n", s->rxq_num);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vmxnet3_activate_device(VMXNET3State *s)
 | 
					static void vmxnet3_activate_device(VMXNET3State *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
@@ -1351,7 +1399,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 | 
				
			|||||||
        VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.misc.numRxQueues);
 | 
					        VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.misc.numRxQueues);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    VMW_CFPRN("Number of TX/RX queues %u/%u", s->txq_num, s->rxq_num);
 | 
					    VMW_CFPRN("Number of TX/RX queues %u/%u", s->txq_num, s->rxq_num);
 | 
				
			||||||
    assert(s->txq_num <= VMXNET3_DEVICE_MAX_TX_QUEUES);
 | 
					    vmxnet3_validate_queues(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qdescr_table_pa =
 | 
					    qdescr_table_pa =
 | 
				
			||||||
        VMXNET3_READ_DRV_SHARED64(s->drv_shmem, devRead.misc.queueDescPA);
 | 
					        VMXNET3_READ_DRV_SHARED64(s->drv_shmem, devRead.misc.queueDescPA);
 | 
				
			||||||
@@ -1447,6 +1495,8 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 | 
				
			|||||||
               sizeof(s->rxq_descr[i].rxq_stats));
 | 
					               sizeof(s->rxq_descr[i].rxq_stats));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vmxnet3_validate_interrupts(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Make sure everything is in place before device activation */
 | 
					    /* Make sure everything is in place before device activation */
 | 
				
			||||||
    smp_wmb();
 | 
					    smp_wmb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2005,7 +2055,6 @@ vmxnet3_cleanup_msix(VMXNET3State *s)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VMXNET3_MSI_NUM_VECTORS   (1)
 | 
					 | 
				
			||||||
#define VMXNET3_MSI_OFFSET        (0x50)
 | 
					#define VMXNET3_MSI_OFFSET        (0x50)
 | 
				
			||||||
#define VMXNET3_USE_64BIT         (true)
 | 
					#define VMXNET3_USE_64BIT         (true)
 | 
				
			||||||
#define VMXNET3_PER_VECTOR_MASK   (false)
 | 
					#define VMXNET3_PER_VECTOR_MASK   (false)
 | 
				
			||||||
@@ -2016,7 +2065,7 @@ vmxnet3_init_msi(VMXNET3State *s)
 | 
				
			|||||||
    PCIDevice *d = PCI_DEVICE(s);
 | 
					    PCIDevice *d = PCI_DEVICE(s);
 | 
				
			||||||
    int res;
 | 
					    int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MSI_NUM_VECTORS,
 | 
					    res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MAX_NMSIX_INTRS,
 | 
				
			||||||
                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK);
 | 
					                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK);
 | 
				
			||||||
    if (0 > res) {
 | 
					    if (0 > res) {
 | 
				
			||||||
        VMW_WRPRN("Failed to initialize MSI, error %d", res);
 | 
					        VMW_WRPRN("Failed to initialize MSI, error %d", res);
 | 
				
			||||||
@@ -2342,6 +2391,9 @@ static int vmxnet3_post_load(void *opaque, int version_id)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vmxnet3_validate_queues(s);
 | 
				
			||||||
 | 
					    vmxnet3_validate_interrupts(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,15 @@
 | 
				
			|||||||
#include "sysemu/sysemu.h"
 | 
					#include "sysemu/sysemu.h"
 | 
				
			||||||
#include "hw/timer/allwinner-a10-pit.h"
 | 
					#include "hw/timer/allwinner-a10-pit.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void a10_pit_update_irq(AwA10PITState *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
 | 
				
			||||||
 | 
					        qemu_set_irq(s->irq[i], !!(s->irq_status & s->irq_enable & (1 << i)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint64_t a10_pit_read(void *opaque, hwaddr offset, unsigned size)
 | 
					static uint64_t a10_pit_read(void *opaque, hwaddr offset, unsigned size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AwA10PITState *s = AW_A10_PIT(opaque);
 | 
					    AwA10PITState *s = AW_A10_PIT(opaque);
 | 
				
			||||||
@@ -65,6 +74,22 @@ static uint64_t a10_pit_read(void *opaque, hwaddr offset, unsigned size)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void a10_pit_set_freq(AwA10PITState *s, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t prescaler, source, source_freq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    prescaler = 1 << extract32(s->control[index], 4, 3);
 | 
				
			||||||
 | 
					    source = extract32(s->control[index], 2, 2);
 | 
				
			||||||
 | 
					    source_freq = s->clk_freq[source];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (source_freq) {
 | 
				
			||||||
 | 
					        ptimer_set_freq(s->timer[index], source_freq / prescaler);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid clock source %u\n",
 | 
				
			||||||
 | 
					                      __func__, source);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void a10_pit_write(void *opaque, hwaddr offset, uint64_t value,
 | 
					static void a10_pit_write(void *opaque, hwaddr offset, uint64_t value,
 | 
				
			||||||
                            unsigned size)
 | 
					                            unsigned size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -74,9 +99,11 @@ static void a10_pit_write(void *opaque, hwaddr offset, uint64_t value,
 | 
				
			|||||||
    switch (offset) {
 | 
					    switch (offset) {
 | 
				
			||||||
    case AW_A10_PIT_TIMER_IRQ_EN:
 | 
					    case AW_A10_PIT_TIMER_IRQ_EN:
 | 
				
			||||||
        s->irq_enable = value;
 | 
					        s->irq_enable = value;
 | 
				
			||||||
 | 
					        a10_pit_update_irq(s);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case AW_A10_PIT_TIMER_IRQ_ST:
 | 
					    case AW_A10_PIT_TIMER_IRQ_ST:
 | 
				
			||||||
        s->irq_status &= ~value;
 | 
					        s->irq_status &= ~value;
 | 
				
			||||||
 | 
					        a10_pit_update_irq(s);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case AW_A10_PIT_TIMER_BASE ... AW_A10_PIT_TIMER_BASE_END:
 | 
					    case AW_A10_PIT_TIMER_BASE ... AW_A10_PIT_TIMER_BASE_END:
 | 
				
			||||||
        index = offset & 0xf0;
 | 
					        index = offset & 0xf0;
 | 
				
			||||||
@@ -85,6 +112,7 @@ static void a10_pit_write(void *opaque, hwaddr offset, uint64_t value,
 | 
				
			|||||||
        switch (offset & 0x0f) {
 | 
					        switch (offset & 0x0f) {
 | 
				
			||||||
        case AW_A10_PIT_TIMER_CONTROL:
 | 
					        case AW_A10_PIT_TIMER_CONTROL:
 | 
				
			||||||
            s->control[index] = value;
 | 
					            s->control[index] = value;
 | 
				
			||||||
 | 
					            a10_pit_set_freq(s, index);
 | 
				
			||||||
            if (s->control[index] & AW_A10_PIT_TIMER_RELOAD) {
 | 
					            if (s->control[index] & AW_A10_PIT_TIMER_RELOAD) {
 | 
				
			||||||
                ptimer_set_count(s->timer[index], s->interval[index]);
 | 
					                ptimer_set_count(s->timer[index], s->interval[index]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -150,6 +178,14 @@ static const MemoryRegionOps a10_pit_ops = {
 | 
				
			|||||||
    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
					    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Property a10_pit_properties[] = {
 | 
				
			||||||
 | 
					    DEFINE_PROP_UINT32("clk0-freq", AwA10PITState, clk_freq[0], 0),
 | 
				
			||||||
 | 
					    DEFINE_PROP_UINT32("clk1-freq", AwA10PITState, clk_freq[1], 0),
 | 
				
			||||||
 | 
					    DEFINE_PROP_UINT32("clk2-freq", AwA10PITState, clk_freq[2], 0),
 | 
				
			||||||
 | 
					    DEFINE_PROP_UINT32("clk3-freq", AwA10PITState, clk_freq[3], 0),
 | 
				
			||||||
 | 
					    DEFINE_PROP_END_OF_LIST(),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const VMStateDescription vmstate_a10_pit = {
 | 
					static const VMStateDescription vmstate_a10_pit = {
 | 
				
			||||||
    .name = "a10.pit",
 | 
					    .name = "a10.pit",
 | 
				
			||||||
    .version_id = 1,
 | 
					    .version_id = 1,
 | 
				
			||||||
@@ -178,11 +214,14 @@ static void a10_pit_reset(DeviceState *dev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    s->irq_enable = 0;
 | 
					    s->irq_enable = 0;
 | 
				
			||||||
    s->irq_status = 0;
 | 
					    s->irq_status = 0;
 | 
				
			||||||
 | 
					    a10_pit_update_irq(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < 6; i++) {
 | 
					    for (i = 0; i < 6; i++) {
 | 
				
			||||||
        s->control[i] = AW_A10_PIT_DEFAULT_CLOCK;
 | 
					        s->control[i] = AW_A10_PIT_DEFAULT_CLOCK;
 | 
				
			||||||
        s->interval[i] = 0;
 | 
					        s->interval[i] = 0;
 | 
				
			||||||
        s->count[i] = 0;
 | 
					        s->count[i] = 0;
 | 
				
			||||||
        ptimer_stop(s->timer[i]);
 | 
					        ptimer_stop(s->timer[i]);
 | 
				
			||||||
 | 
					        a10_pit_set_freq(s, i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    s->watch_dog_mode = 0;
 | 
					    s->watch_dog_mode = 0;
 | 
				
			||||||
    s->watch_dog_control = 0;
 | 
					    s->watch_dog_control = 0;
 | 
				
			||||||
@@ -193,18 +232,17 @@ static void a10_pit_reset(DeviceState *dev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void a10_pit_timer_cb(void *opaque)
 | 
					static void a10_pit_timer_cb(void *opaque)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AwA10PITState *s = AW_A10_PIT(opaque);
 | 
					    AwA10TimerContext *tc = opaque;
 | 
				
			||||||
    uint8_t i;
 | 
					    AwA10PITState *s = tc->container;
 | 
				
			||||||
 | 
					    uint8_t i = tc->index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
 | 
					    if (s->control[i] & AW_A10_PIT_TIMER_EN) {
 | 
				
			||||||
        if (s->control[i] & AW_A10_PIT_TIMER_EN) {
 | 
					        s->irq_status |= 1 << i;
 | 
				
			||||||
            s->irq_status |= 1 << i;
 | 
					        if (s->control[i] & AW_A10_PIT_TIMER_MODE) {
 | 
				
			||||||
            if (s->control[i] & AW_A10_PIT_TIMER_MODE) {
 | 
					            ptimer_stop(s->timer[i]);
 | 
				
			||||||
                ptimer_stop(s->timer[i]);
 | 
					            s->control[i] &= ~AW_A10_PIT_TIMER_EN;
 | 
				
			||||||
                s->control[i] &= ~AW_A10_PIT_TIMER_EN;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            qemu_irq_pulse(s->irq[i]);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        a10_pit_update_irq(s);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -223,9 +261,12 @@ static void a10_pit_init(Object *obj)
 | 
				
			|||||||
    sysbus_init_mmio(sbd, &s->iomem);
 | 
					    sysbus_init_mmio(sbd, &s->iomem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
 | 
					    for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
 | 
				
			||||||
        bh[i] = qemu_bh_new(a10_pit_timer_cb, s);
 | 
					        AwA10TimerContext *tc = &s->timer_context[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tc->container = s;
 | 
				
			||||||
 | 
					        tc->index = i;
 | 
				
			||||||
 | 
					        bh[i] = qemu_bh_new(a10_pit_timer_cb, tc);
 | 
				
			||||||
        s->timer[i] = ptimer_init(bh[i]);
 | 
					        s->timer[i] = ptimer_init(bh[i]);
 | 
				
			||||||
        ptimer_set_freq(s->timer[i], 240000);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -234,6 +275,7 @@ static void a10_pit_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
					    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dc->reset = a10_pit_reset;
 | 
					    dc->reset = a10_pit_reset;
 | 
				
			||||||
 | 
					    dc->props = a10_pit_properties;
 | 
				
			||||||
    dc->desc = "allwinner a10 timer";
 | 
					    dc->desc = "allwinner a10 timer";
 | 
				
			||||||
    dc->vmsd = &vmstate_a10_pit;
 | 
					    dc->vmsd = &vmstate_a10_pit;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -346,11 +346,13 @@ static void cadence_ttc_write(void *opaque, hwaddr offset,
 | 
				
			|||||||
    case 0x34:
 | 
					    case 0x34:
 | 
				
			||||||
    case 0x38:
 | 
					    case 0x38:
 | 
				
			||||||
        s->reg_match[0] = value & 0xffff;
 | 
					        s->reg_match[0] = value & 0xffff;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case 0x3c: /* match register */
 | 
					    case 0x3c: /* match register */
 | 
				
			||||||
    case 0x40:
 | 
					    case 0x40:
 | 
				
			||||||
    case 0x44:
 | 
					    case 0x44:
 | 
				
			||||||
        s->reg_match[1] = value & 0xffff;
 | 
					        s->reg_match[1] = value & 0xffff;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case 0x48: /* match register */
 | 
					    case 0x48: /* match register */
 | 
				
			||||||
    case 0x4c:
 | 
					    case 0x4c:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,10 @@ common-obj-y                          += ccid-card-passthru.o
 | 
				
			|||||||
common-obj-$(CONFIG_SMARTCARD_NSS)    += ccid-card-emulated.o
 | 
					common-obj-$(CONFIG_SMARTCARD_NSS)    += ccid-card-emulated.o
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(CONFIG_POSIX),y)
 | 
				
			||||||
 | 
					common-obj-$(CONFIG_USB_STORAGE_MTP)  += dev-mtp.o
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# usb redirection
 | 
					# usb redirection
 | 
				
			||||||
common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
 | 
					common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,7 @@ typedef struct msos_compat_hdr {
 | 
				
			|||||||
typedef struct msos_compat_func {
 | 
					typedef struct msos_compat_func {
 | 
				
			||||||
    uint8_t  bFirstInterfaceNumber;
 | 
					    uint8_t  bFirstInterfaceNumber;
 | 
				
			||||||
    uint8_t  reserved_1;
 | 
					    uint8_t  reserved_1;
 | 
				
			||||||
    uint8_t  compatibleId[8];
 | 
					    char     compatibleId[8];
 | 
				
			||||||
    uint8_t  subCompatibleId[8];
 | 
					    uint8_t  subCompatibleId[8];
 | 
				
			||||||
    uint8_t  reserved_2[6];
 | 
					    uint8_t  reserved_2[6];
 | 
				
			||||||
} QEMU_PACKED msos_compat_func;
 | 
					} QEMU_PACKED msos_compat_func;
 | 
				
			||||||
@@ -59,6 +59,10 @@ static int usb_desc_msos_compat(const USBDesc *desc, uint8_t *dest)
 | 
				
			|||||||
    func = (void *)(dest + length);
 | 
					    func = (void *)(dest + length);
 | 
				
			||||||
    func->bFirstInterfaceNumber = 0;
 | 
					    func->bFirstInterfaceNumber = 0;
 | 
				
			||||||
    func->reserved_1 = 0x01;
 | 
					    func->reserved_1 = 0x01;
 | 
				
			||||||
 | 
					    if (desc->msos->CompatibleID) {
 | 
				
			||||||
 | 
					        snprintf(func->compatibleId, sizeof(func->compatibleId),
 | 
				
			||||||
 | 
					                 "%s", desc->msos->CompatibleID);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    length += sizeof(*func);
 | 
					    length += sizeof(*func);
 | 
				
			||||||
    count++;
 | 
					    count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,6 +184,7 @@ struct USBDescOther {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct USBDescMSOS {
 | 
					struct USBDescMSOS {
 | 
				
			||||||
 | 
					    const char                *CompatibleID;
 | 
				
			||||||
    const wchar_t             *Label;
 | 
					    const wchar_t             *Label;
 | 
				
			||||||
    bool                      SelectiveSuspendEnabled;
 | 
					    bool                      SelectiveSuspendEnabled;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1103
									
								
								hw/usb/dev-mtp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1103
									
								
								hw/usb/dev-mtp.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -162,3 +162,55 @@
 | 
				
			|||||||
#define stw(p, v) stw_data(p, v)
 | 
					#define stw(p, v) stw_data(p, v)
 | 
				
			||||||
#define stl(p, v) stl_data(p, v)
 | 
					#define stl(p, v) stl_data(p, v)
 | 
				
			||||||
#define stq(p, v) stq_data(p, v)
 | 
					#define stq(p, v) stq_data(p, v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * tlb_vaddr_to_host:
 | 
				
			||||||
 | 
					 * @env: CPUArchState
 | 
				
			||||||
 | 
					 * @addr: guest virtual address to look up
 | 
				
			||||||
 | 
					 * @access_type: 0 for read, 1 for write, 2 for execute
 | 
				
			||||||
 | 
					 * @mmu_idx: MMU index to use for lookup
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Look up the specified guest virtual index in the TCG softmmu TLB.
 | 
				
			||||||
 | 
					 * If the TLB contains a host virtual address suitable for direct RAM
 | 
				
			||||||
 | 
					 * access, then return it. Otherwise (TLB miss, TLB entry is for an
 | 
				
			||||||
 | 
					 * I/O access, etc) return NULL.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is the equivalent of the initial fast-path code used by
 | 
				
			||||||
 | 
					 * TCG backends for guest load and store accesses.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
 | 
				
			||||||
 | 
					                                      int access_type, int mmu_idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 | 
				
			||||||
 | 
					    CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
 | 
				
			||||||
 | 
					    target_ulong tlb_addr;
 | 
				
			||||||
 | 
					    uintptr_t haddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (access_type) {
 | 
				
			||||||
 | 
					    case 0:
 | 
				
			||||||
 | 
					        tlb_addr = tlbentry->addr_read;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case 1:
 | 
				
			||||||
 | 
					        tlb_addr = tlbentry->addr_write;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					        tlb_addr = tlbentry->addr_code;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        g_assert_not_reached();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((addr & TARGET_PAGE_MASK)
 | 
				
			||||||
 | 
					        != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
 | 
				
			||||||
 | 
					        /* TLB entry is for a different page */
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tlb_addr & ~TARGET_PAGE_MASK) {
 | 
				
			||||||
 | 
					        /* IO access */
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    haddr = addr + env->tlb_table[mmu_idx][index].addend;
 | 
				
			||||||
 | 
					    return (void *)haddr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -144,6 +144,7 @@
 | 
				
			|||||||
#define MII_BMSR_10T_FD     (1 << 12)
 | 
					#define MII_BMSR_10T_FD     (1 << 12)
 | 
				
			||||||
#define MII_BMSR_10T_HD     (1 << 11)
 | 
					#define MII_BMSR_10T_HD     (1 << 11)
 | 
				
			||||||
#define MII_BMSR_MFPS       (1 << 6)
 | 
					#define MII_BMSR_MFPS       (1 << 6)
 | 
				
			||||||
 | 
					#define MII_BMSR_AN_COMP    (1 << 5)
 | 
				
			||||||
#define MII_BMSR_AUTONEG    (1 << 3)
 | 
					#define MII_BMSR_AUTONEG    (1 << 3)
 | 
				
			||||||
#define MII_BMSR_LINK_ST    (1 << 2)
 | 
					#define MII_BMSR_LINK_ST    (1 << 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,13 +35,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define AW_A10_PIT_DEFAULT_CLOCK   0x4
 | 
					#define AW_A10_PIT_DEFAULT_CLOCK   0x4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct AwA10PITState {
 | 
					typedef struct AwA10PITState AwA10PITState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct AwA10TimerContext {
 | 
				
			||||||
 | 
					    AwA10PITState *container;
 | 
				
			||||||
 | 
					    int index;
 | 
				
			||||||
 | 
					} AwA10TimerContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct AwA10PITState {
 | 
				
			||||||
    /*< private >*/
 | 
					    /*< private >*/
 | 
				
			||||||
    SysBusDevice parent_obj;
 | 
					    SysBusDevice parent_obj;
 | 
				
			||||||
    /*< public >*/
 | 
					    /*< public >*/
 | 
				
			||||||
    qemu_irq irq[AW_A10_PIT_TIMER_NR];
 | 
					    qemu_irq irq[AW_A10_PIT_TIMER_NR];
 | 
				
			||||||
    ptimer_state * timer[AW_A10_PIT_TIMER_NR];
 | 
					    ptimer_state * timer[AW_A10_PIT_TIMER_NR];
 | 
				
			||||||
 | 
					    AwA10TimerContext timer_context[AW_A10_PIT_TIMER_NR];
 | 
				
			||||||
    MemoryRegion iomem;
 | 
					    MemoryRegion iomem;
 | 
				
			||||||
 | 
					    uint32_t clk_freq[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t irq_enable;
 | 
					    uint32_t irq_enable;
 | 
				
			||||||
    uint32_t irq_status;
 | 
					    uint32_t irq_status;
 | 
				
			||||||
@@ -53,6 +62,6 @@ typedef struct AwA10PITState {
 | 
				
			|||||||
    uint32_t count_lo;
 | 
					    uint32_t count_lo;
 | 
				
			||||||
    uint32_t count_hi;
 | 
					    uint32_t count_hi;
 | 
				
			||||||
    uint32_t count_ctl;
 | 
					    uint32_t count_ctl;
 | 
				
			||||||
} AwA10PITState;
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -441,7 +441,7 @@ static int kvm_physical_sync_dirty_bitmap(MemoryRegionSection *section)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        d.slot = mem->slot;
 | 
					        d.slot = mem->slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) < 0) {
 | 
					        if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
 | 
				
			||||||
            DPRINTF("ioctl failed %d\n", errno);
 | 
					            DPRINTF("ioctl failed %d\n", errno);
 | 
				
			||||||
            ret = -1;
 | 
					            ret = -1;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -483,17 +483,17 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
 | 
				
			|||||||
    addr = env->regs[2];
 | 
					    addr = env->regs[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (get_user_u64(oldval, env->regs[0])) {
 | 
					    if (get_user_u64(oldval, env->regs[0])) {
 | 
				
			||||||
        env->cp15.c6_data = env->regs[0];
 | 
					        env->exception.vaddress = env->regs[0];
 | 
				
			||||||
        goto segv;
 | 
					        goto segv;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (get_user_u64(newval, env->regs[1])) {
 | 
					    if (get_user_u64(newval, env->regs[1])) {
 | 
				
			||||||
        env->cp15.c6_data = env->regs[1];
 | 
					        env->exception.vaddress = env->regs[1];
 | 
				
			||||||
        goto segv;
 | 
					        goto segv;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (get_user_u64(val, addr)) {
 | 
					    if (get_user_u64(val, addr)) {
 | 
				
			||||||
        env->cp15.c6_data = addr;
 | 
					        env->exception.vaddress = addr;
 | 
				
			||||||
        goto segv;
 | 
					        goto segv;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -501,7 +501,7 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
 | 
				
			|||||||
        val = newval;
 | 
					        val = newval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (put_user_u64(val, addr)) {
 | 
					        if (put_user_u64(val, addr)) {
 | 
				
			||||||
            env->cp15.c6_data = addr;
 | 
					            env->exception.vaddress = addr;
 | 
				
			||||||
            goto segv;
 | 
					            goto segv;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -523,7 +523,7 @@ segv:
 | 
				
			|||||||
    info.si_errno = 0;
 | 
					    info.si_errno = 0;
 | 
				
			||||||
    /* XXX: check env->error_code */
 | 
					    /* XXX: check env->error_code */
 | 
				
			||||||
    info.si_code = TARGET_SEGV_MAPERR;
 | 
					    info.si_code = TARGET_SEGV_MAPERR;
 | 
				
			||||||
    info._sifields._sigfault._addr = env->cp15.c6_data;
 | 
					    info._sifields._sigfault._addr = env->exception.vaddress;
 | 
				
			||||||
    queue_signal(env, info.si_signo, &info);
 | 
					    queue_signal(env, info.si_signo, &info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end_exclusive();
 | 
					    end_exclusive();
 | 
				
			||||||
@@ -620,14 +620,14 @@ static int do_strex(CPUARMState *env)
 | 
				
			|||||||
        abort();
 | 
					        abort();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (segv) {
 | 
					    if (segv) {
 | 
				
			||||||
        env->cp15.c6_data = addr;
 | 
					        env->exception.vaddress = addr;
 | 
				
			||||||
        goto done;
 | 
					        goto done;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (size == 3) {
 | 
					    if (size == 3) {
 | 
				
			||||||
        uint32_t valhi;
 | 
					        uint32_t valhi;
 | 
				
			||||||
        segv = get_user_u32(valhi, addr + 4);
 | 
					        segv = get_user_u32(valhi, addr + 4);
 | 
				
			||||||
        if (segv) {
 | 
					        if (segv) {
 | 
				
			||||||
            env->cp15.c6_data = addr + 4;
 | 
					            env->exception.vaddress = addr + 4;
 | 
				
			||||||
            goto done;
 | 
					            goto done;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        val = deposit64(val, 32, 32, valhi);
 | 
					        val = deposit64(val, 32, 32, valhi);
 | 
				
			||||||
@@ -650,14 +650,14 @@ static int do_strex(CPUARMState *env)
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (segv) {
 | 
					    if (segv) {
 | 
				
			||||||
        env->cp15.c6_data = addr;
 | 
					        env->exception.vaddress = addr;
 | 
				
			||||||
        goto done;
 | 
					        goto done;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (size == 3) {
 | 
					    if (size == 3) {
 | 
				
			||||||
        val = env->regs[(env->exclusive_info >> 12) & 0xf];
 | 
					        val = env->regs[(env->exclusive_info >> 12) & 0xf];
 | 
				
			||||||
        segv = put_user_u32(val, addr + 4);
 | 
					        segv = put_user_u32(val, addr + 4);
 | 
				
			||||||
        if (segv) {
 | 
					        if (segv) {
 | 
				
			||||||
            env->cp15.c6_data = addr + 4;
 | 
					            env->exception.vaddress = addr + 4;
 | 
				
			||||||
            goto done;
 | 
					            goto done;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -832,12 +832,14 @@ void cpu_loop(CPUARMState *env)
 | 
				
			|||||||
        case EXCP_INTERRUPT:
 | 
					        case EXCP_INTERRUPT:
 | 
				
			||||||
            /* just indicate that signals should be handled asap */
 | 
					            /* just indicate that signals should be handled asap */
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case EXCP_STREX:
 | 
				
			||||||
 | 
					            if (!do_strex(env)) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            /* fall through for segv */
 | 
				
			||||||
        case EXCP_PREFETCH_ABORT:
 | 
					        case EXCP_PREFETCH_ABORT:
 | 
				
			||||||
            addr = env->cp15.c6_insn;
 | 
					 | 
				
			||||||
            goto do_segv;
 | 
					 | 
				
			||||||
        case EXCP_DATA_ABORT:
 | 
					        case EXCP_DATA_ABORT:
 | 
				
			||||||
            addr = env->cp15.c6_data;
 | 
					            addr = env->exception.vaddress;
 | 
				
			||||||
        do_segv:
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                info.si_signo = SIGSEGV;
 | 
					                info.si_signo = SIGSEGV;
 | 
				
			||||||
                info.si_errno = 0;
 | 
					                info.si_errno = 0;
 | 
				
			||||||
@@ -865,12 +867,6 @@ void cpu_loop(CPUARMState *env)
 | 
				
			|||||||
            if (do_kernel_trap(env))
 | 
					            if (do_kernel_trap(env))
 | 
				
			||||||
              goto error;
 | 
					              goto error;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case EXCP_STREX:
 | 
					 | 
				
			||||||
            if (do_strex(env)) {
 | 
					 | 
				
			||||||
                addr = env->cp15.c6_data;
 | 
					 | 
				
			||||||
                goto do_segv;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
        error:
 | 
					        error:
 | 
				
			||||||
            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 | 
					            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 | 
				
			||||||
@@ -933,7 +929,7 @@ static int do_strex_a64(CPUARMState *env)
 | 
				
			|||||||
        abort();
 | 
					        abort();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (segv) {
 | 
					    if (segv) {
 | 
				
			||||||
        env->cp15.c6_data = addr;
 | 
					        env->exception.vaddress = addr;
 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (val != env->exclusive_val) {
 | 
					    if (val != env->exclusive_val) {
 | 
				
			||||||
@@ -946,7 +942,7 @@ static int do_strex_a64(CPUARMState *env)
 | 
				
			|||||||
            segv = get_user_u64(val, addr + 8);
 | 
					            segv = get_user_u64(val, addr + 8);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (segv) {
 | 
					        if (segv) {
 | 
				
			||||||
            env->cp15.c6_data = addr + (size == 2 ? 4 : 8);
 | 
					            env->exception.vaddress = addr + (size == 2 ? 4 : 8);
 | 
				
			||||||
            goto error;
 | 
					            goto error;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (val != env->exclusive_high) {
 | 
					        if (val != env->exclusive_high) {
 | 
				
			||||||
@@ -981,7 +977,7 @@ static int do_strex_a64(CPUARMState *env)
 | 
				
			|||||||
            segv = put_user_u64(val, addr + 8);
 | 
					            segv = put_user_u64(val, addr + 8);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (segv) {
 | 
					        if (segv) {
 | 
				
			||||||
            env->cp15.c6_data = addr + (size == 2 ? 4 : 8);
 | 
					            env->exception.vaddress = addr + (size == 2 ? 4 : 8);
 | 
				
			||||||
            goto error;
 | 
					            goto error;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -1037,12 +1033,14 @@ void cpu_loop(CPUARMState *env)
 | 
				
			|||||||
            info._sifields._sigfault._addr = env->pc;
 | 
					            info._sifields._sigfault._addr = env->pc;
 | 
				
			||||||
            queue_signal(env, info.si_signo, &info);
 | 
					            queue_signal(env, info.si_signo, &info);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case EXCP_STREX:
 | 
				
			||||||
 | 
					            if (!do_strex_a64(env)) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            /* fall through for segv */
 | 
				
			||||||
        case EXCP_PREFETCH_ABORT:
 | 
					        case EXCP_PREFETCH_ABORT:
 | 
				
			||||||
            addr = env->cp15.c6_insn;
 | 
					 | 
				
			||||||
            goto do_segv;
 | 
					 | 
				
			||||||
        case EXCP_DATA_ABORT:
 | 
					        case EXCP_DATA_ABORT:
 | 
				
			||||||
            addr = env->cp15.c6_data;
 | 
					            addr = env->exception.vaddress;
 | 
				
			||||||
        do_segv:
 | 
					 | 
				
			||||||
            info.si_signo = SIGSEGV;
 | 
					            info.si_signo = SIGSEGV;
 | 
				
			||||||
            info.si_errno = 0;
 | 
					            info.si_errno = 0;
 | 
				
			||||||
            /* XXX: check env->error_code */
 | 
					            /* XXX: check env->error_code */
 | 
				
			||||||
@@ -1060,12 +1058,6 @@ void cpu_loop(CPUARMState *env)
 | 
				
			|||||||
                queue_signal(env, info.si_signo, &info);
 | 
					                queue_signal(env, info.si_signo, &info);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case EXCP_STREX:
 | 
					 | 
				
			||||||
            if (do_strex_a64(env)) {
 | 
					 | 
				
			||||||
                addr = env->cp15.c6_data;
 | 
					 | 
				
			||||||
                goto do_segv;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 | 
					            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 | 
				
			||||||
                    trapnr);
 | 
					                    trapnr);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1225,7 +1225,8 @@ Object *object_resolve_path_component(Object *parent, const gchar *part)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (object_property_is_link(prop)) {
 | 
					    if (object_property_is_link(prop)) {
 | 
				
			||||||
        return *(Object **)prop->opaque;
 | 
					        LinkProperty *lprop = prop->opaque;
 | 
				
			||||||
 | 
					        return *lprop->child;
 | 
				
			||||||
    } else if (object_property_is_child(prop)) {
 | 
					    } else if (object_property_is_child(prop)) {
 | 
				
			||||||
        return prop->opaque;
 | 
					        return prop->opaque;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -116,6 +116,7 @@ typedef struct ARMCPU {
 | 
				
			|||||||
    uint32_t reset_fpsid;
 | 
					    uint32_t reset_fpsid;
 | 
				
			||||||
    uint32_t mvfr0;
 | 
					    uint32_t mvfr0;
 | 
				
			||||||
    uint32_t mvfr1;
 | 
					    uint32_t mvfr1;
 | 
				
			||||||
 | 
					    uint32_t mvfr2;
 | 
				
			||||||
    uint32_t ctr;
 | 
					    uint32_t ctr;
 | 
				
			||||||
    uint32_t reset_sctlr;
 | 
					    uint32_t reset_sctlr;
 | 
				
			||||||
    uint32_t id_pfr0;
 | 
					    uint32_t id_pfr0;
 | 
				
			||||||
@@ -147,9 +148,12 @@ typedef struct ARMCPU {
 | 
				
			|||||||
     * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
 | 
					     * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    uint32_t ccsidr[16];
 | 
					    uint32_t ccsidr[16];
 | 
				
			||||||
    uint32_t reset_cbar;
 | 
					    uint64_t reset_cbar;
 | 
				
			||||||
    uint32_t reset_auxcr;
 | 
					    uint32_t reset_auxcr;
 | 
				
			||||||
    bool reset_hivecs;
 | 
					    bool reset_hivecs;
 | 
				
			||||||
 | 
					    /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
 | 
				
			||||||
 | 
					    uint32_t dcz_blocksize;
 | 
				
			||||||
 | 
					    uint64_t rvbar;
 | 
				
			||||||
} ARMCPU;
 | 
					} ARMCPU;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TYPE_AARCH64_CPU "aarch64-cpu"
 | 
					#define TYPE_AARCH64_CPU "aarch64-cpu"
 | 
				
			||||||
@@ -196,10 +200,10 @@ void arm_gt_ptimer_cb(void *opaque);
 | 
				
			|||||||
void arm_gt_vtimer_cb(void *opaque);
 | 
					void arm_gt_vtimer_cb(void *opaque);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TARGET_AARCH64
 | 
					#ifdef TARGET_AARCH64
 | 
				
			||||||
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
 | 
					 | 
				
			||||||
                            fprintf_function cpu_fprintf, int flags);
 | 
					 | 
				
			||||||
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 | 
					int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 | 
				
			||||||
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 | 
					int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void aarch64_cpu_do_interrupt(CPUState *cs);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
 | 
					#include "internals.h"
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "hw/qdev-properties.h"
 | 
					#include "hw/qdev-properties.h"
 | 
				
			||||||
#include "qapi/qmp/qerror.h"
 | 
					#include "qapi/qmp/qerror.h"
 | 
				
			||||||
@@ -87,6 +88,7 @@ static void arm_cpu_reset(CPUState *s)
 | 
				
			|||||||
    env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
 | 
					    env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
 | 
				
			||||||
    env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
 | 
					    env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
 | 
				
			||||||
    env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
 | 
					    env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
 | 
				
			||||||
 | 
					    env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 | 
					    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 | 
				
			||||||
        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
 | 
					        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
 | 
				
			||||||
@@ -99,8 +101,16 @@ static void arm_cpu_reset(CPUState *s)
 | 
				
			|||||||
        env->pstate = PSTATE_MODE_EL0t;
 | 
					        env->pstate = PSTATE_MODE_EL0t;
 | 
				
			||||||
        /* Userspace expects access to CTL_EL0 and the cache ops */
 | 
					        /* Userspace expects access to CTL_EL0 and the cache ops */
 | 
				
			||||||
        env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI;
 | 
					        env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI;
 | 
				
			||||||
 | 
					        /* and to the FP/Neon instructions */
 | 
				
			||||||
 | 
					        env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        env->pstate = PSTATE_MODE_EL1h;
 | 
					        env->pstate = PSTATE_MODE_EL1h;
 | 
				
			||||||
 | 
					        env->pc = cpu->rvbar;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					#if defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					        /* Userspace expects access to cp10 and cp11 for FP/Neon */
 | 
				
			||||||
 | 
					        env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 4, 0xf);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -252,16 +262,20 @@ static void arm_cpu_initfn(Object *obj)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Property arm_cpu_reset_cbar_property =
 | 
					static Property arm_cpu_reset_cbar_property =
 | 
				
			||||||
            DEFINE_PROP_UINT32("reset-cbar", ARMCPU, reset_cbar, 0);
 | 
					            DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Property arm_cpu_reset_hivecs_property =
 | 
					static Property arm_cpu_reset_hivecs_property =
 | 
				
			||||||
            DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);
 | 
					            DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Property arm_cpu_rvbar_property =
 | 
				
			||||||
 | 
					            DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void arm_cpu_post_init(Object *obj)
 | 
					static void arm_cpu_post_init(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ARMCPU *cpu = ARM_CPU(obj);
 | 
					    ARMCPU *cpu = ARM_CPU(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (arm_feature(&cpu->env, ARM_FEATURE_CBAR)) {
 | 
					    if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
 | 
				
			||||||
 | 
					        arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
 | 
				
			||||||
        qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property,
 | 
					        qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property,
 | 
				
			||||||
                                 &error_abort);
 | 
					                                 &error_abort);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -270,6 +284,11 @@ static void arm_cpu_post_init(Object *obj)
 | 
				
			|||||||
        qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property,
 | 
					        qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property,
 | 
				
			||||||
                                 &error_abort);
 | 
					                                 &error_abort);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
 | 
				
			||||||
 | 
					        qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property,
 | 
				
			||||||
 | 
					                                 &error_abort);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void arm_cpu_finalizefn(Object *obj)
 | 
					static void arm_cpu_finalizefn(Object *obj)
 | 
				
			||||||
@@ -331,6 +350,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
				
			|||||||
        set_feature(env, ARM_FEATURE_V7MP);
 | 
					        set_feature(env, ARM_FEATURE_V7MP);
 | 
				
			||||||
        set_feature(env, ARM_FEATURE_PXN);
 | 
					        set_feature(env, ARM_FEATURE_PXN);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
 | 
				
			||||||
 | 
					        set_feature(env, ARM_FEATURE_CBAR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cpu->reset_hivecs) {
 | 
					    if (cpu->reset_hivecs) {
 | 
				
			||||||
            cpu->reset_sctlr |= (1 << 13);
 | 
					            cpu->reset_sctlr |= (1 << 13);
 | 
				
			||||||
@@ -417,7 +439,7 @@ static void arm1026_initfn(Object *obj)
 | 
				
			|||||||
        ARMCPRegInfo ifar = {
 | 
					        ARMCPRegInfo ifar = {
 | 
				
			||||||
            .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
 | 
					            .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
 | 
				
			||||||
            .access = PL1_RW,
 | 
					            .access = PL1_RW,
 | 
				
			||||||
            .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
 | 
					            .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1),
 | 
				
			||||||
            .resetvalue = 0
 | 
					            .resetvalue = 0
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        define_one_arm_cp_reg(cpu, &ifar);
 | 
					        define_one_arm_cp_reg(cpu, &ifar);
 | 
				
			||||||
@@ -722,7 +744,7 @@ static void cortex_a15_initfn(Object *obj)
 | 
				
			|||||||
    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_CBAR);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_LPAE);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_LPAE);
 | 
				
			||||||
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
 | 
					    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
 | 
				
			||||||
    cpu->midr = 0x412fc0f1;
 | 
					    cpu->midr = 0x412fc0f1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -111,11 +111,6 @@ typedef struct ARMGenericTimer {
 | 
				
			|||||||
#define GTIMER_VIRT 1
 | 
					#define GTIMER_VIRT 1
 | 
				
			||||||
#define NUM_GTIMERS 2
 | 
					#define NUM_GTIMERS 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Scale factor for generic timers, ie number of ns per tick.
 | 
					 | 
				
			||||||
 * This gives a 62.5MHz timer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define GTIMER_SCALE 16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct CPUARMState {
 | 
					typedef struct CPUARMState {
 | 
				
			||||||
    /* Regs for current mode.  */
 | 
					    /* Regs for current mode.  */
 | 
				
			||||||
    uint32_t regs[16];
 | 
					    uint32_t regs[16];
 | 
				
			||||||
@@ -148,7 +143,7 @@ typedef struct CPUARMState {
 | 
				
			|||||||
    uint32_t spsr;
 | 
					    uint32_t spsr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Banked registers.  */
 | 
					    /* Banked registers.  */
 | 
				
			||||||
    uint32_t banked_spsr[6];
 | 
					    uint64_t banked_spsr[6];
 | 
				
			||||||
    uint32_t banked_r13[6];
 | 
					    uint32_t banked_r13[6];
 | 
				
			||||||
    uint32_t banked_r14[6];
 | 
					    uint32_t banked_r14[6];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -165,7 +160,10 @@ typedef struct CPUARMState {
 | 
				
			|||||||
    uint32_t GE; /* cpsr[19:16] */
 | 
					    uint32_t GE; /* cpsr[19:16] */
 | 
				
			||||||
    uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
 | 
					    uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
 | 
				
			||||||
    uint32_t condexec_bits; /* IT bits.  cpsr[15:10,26:25].  */
 | 
					    uint32_t condexec_bits; /* IT bits.  cpsr[15:10,26:25].  */
 | 
				
			||||||
    uint32_t daif; /* exception masks, in the bits they are in in PSTATE */
 | 
					    uint64_t daif; /* exception masks, in the bits they are in in PSTATE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint64_t elr_el1; /* AArch64 ELR_EL1 */
 | 
				
			||||||
 | 
					    uint64_t sp_el[2]; /* AArch64 banked stack pointers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* System control coprocessor (cp15) */
 | 
					    /* System control coprocessor (cp15) */
 | 
				
			||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
@@ -184,13 +182,13 @@ typedef struct CPUARMState {
 | 
				
			|||||||
        uint32_t c2_insn; /* MPU instruction cachable bits.  */
 | 
					        uint32_t c2_insn; /* MPU instruction cachable bits.  */
 | 
				
			||||||
        uint32_t c3; /* MMU domain access control register
 | 
					        uint32_t c3; /* MMU domain access control register
 | 
				
			||||||
                        MPU write buffer control.  */
 | 
					                        MPU write buffer control.  */
 | 
				
			||||||
        uint32_t c5_insn; /* Fault status registers.  */
 | 
					        uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */
 | 
				
			||||||
        uint32_t c5_data;
 | 
					        uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
 | 
				
			||||||
 | 
					        uint32_t ifsr_el2; /* Fault status registers.  */
 | 
				
			||||||
 | 
					        uint64_t esr_el1;
 | 
				
			||||||
        uint32_t c6_region[8]; /* MPU base/size registers.  */
 | 
					        uint32_t c6_region[8]; /* MPU base/size registers.  */
 | 
				
			||||||
        uint32_t c6_insn; /* Fault address registers.  */
 | 
					        uint64_t far_el1; /* Fault address registers.  */
 | 
				
			||||||
        uint32_t c6_data;
 | 
					        uint64_t par_el1;  /* Translation result. */
 | 
				
			||||||
        uint32_t c7_par;  /* Translation result. */
 | 
					 | 
				
			||||||
        uint32_t c7_par_hi;  /* Translation result, high 32 bits */
 | 
					 | 
				
			||||||
        uint32_t c9_insn; /* Cache lockdown registers.  */
 | 
					        uint32_t c9_insn; /* Cache lockdown registers.  */
 | 
				
			||||||
        uint32_t c9_data;
 | 
					        uint32_t c9_data;
 | 
				
			||||||
        uint32_t c9_pmcr; /* performance monitor control register */
 | 
					        uint32_t c9_pmcr; /* performance monitor control register */
 | 
				
			||||||
@@ -202,7 +200,7 @@ typedef struct CPUARMState {
 | 
				
			|||||||
        uint64_t mair_el1;
 | 
					        uint64_t mair_el1;
 | 
				
			||||||
        uint64_t c12_vbar; /* vector base address register */
 | 
					        uint64_t c12_vbar; /* vector base address register */
 | 
				
			||||||
        uint32_t c13_fcse; /* FCSE PID.  */
 | 
					        uint32_t c13_fcse; /* FCSE PID.  */
 | 
				
			||||||
        uint32_t c13_context; /* Context ID.  */
 | 
					        uint64_t contextidr_el1; /* Context ID.  */
 | 
				
			||||||
        uint64_t tpidr_el0; /* User RW Thread register.  */
 | 
					        uint64_t tpidr_el0; /* User RW Thread register.  */
 | 
				
			||||||
        uint64_t tpidrro_el0; /* User RO Thread register.  */
 | 
					        uint64_t tpidrro_el0; /* User RO Thread register.  */
 | 
				
			||||||
        uint64_t tpidr_el1; /* Privileged Thread register.  */
 | 
					        uint64_t tpidr_el1; /* Privileged Thread register.  */
 | 
				
			||||||
@@ -238,6 +236,21 @@ typedef struct CPUARMState {
 | 
				
			|||||||
        int pending_exception;
 | 
					        int pending_exception;
 | 
				
			||||||
    } v7m;
 | 
					    } v7m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Information associated with an exception about to be taken:
 | 
				
			||||||
 | 
					     * code which raises an exception must set cs->exception_index and
 | 
				
			||||||
 | 
					     * the relevant parts of this structure; the cpu_do_interrupt function
 | 
				
			||||||
 | 
					     * will then set the guest-visible registers as part of the exception
 | 
				
			||||||
 | 
					     * entry process.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        uint32_t syndrome; /* AArch64 format syndrome register */
 | 
				
			||||||
 | 
					        uint32_t fsr; /* AArch32 format fault status register info */
 | 
				
			||||||
 | 
					        uint64_t vaddress; /* virtual addr associated with exception, if any */
 | 
				
			||||||
 | 
					        /* If we implement EL2 we will also need to store information
 | 
				
			||||||
 | 
					         * about the intermediate physical address for stage 2 faults.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					    } exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Thumb-2 EE state.  */
 | 
					    /* Thumb-2 EE state.  */
 | 
				
			||||||
    uint32_t teecr;
 | 
					    uint32_t teecr;
 | 
				
			||||||
    uint32_t teehbr;
 | 
					    uint32_t teehbr;
 | 
				
			||||||
@@ -322,11 +335,7 @@ typedef struct CPUARMState {
 | 
				
			|||||||
#include "cpu-qom.h"
 | 
					#include "cpu-qom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARMCPU *cpu_arm_init(const char *cpu_model);
 | 
					ARMCPU *cpu_arm_init(const char *cpu_model);
 | 
				
			||||||
void arm_translate_init(void);
 | 
					 | 
				
			||||||
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
 | 
					 | 
				
			||||||
int cpu_arm_exec(CPUARMState *s);
 | 
					int cpu_arm_exec(CPUARMState *s);
 | 
				
			||||||
int bank_number(int mode);
 | 
					 | 
				
			||||||
void switch_mode(CPUARMState *, int);
 | 
					 | 
				
			||||||
uint32_t do_arm_semihosting(CPUARMState *env);
 | 
					uint32_t do_arm_semihosting(CPUARMState *env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool is_a64(CPUARMState *env)
 | 
					static inline bool is_a64(CPUARMState *env)
 | 
				
			||||||
@@ -425,6 +434,7 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
 | 
				
			|||||||
 * Only these are valid when in AArch64 mode; in
 | 
					 * Only these are valid when in AArch64 mode; in
 | 
				
			||||||
 * AArch32 mode SPSRs are basically CPSR-format.
 | 
					 * AArch32 mode SPSRs are basically CPSR-format.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#define PSTATE_SP (1U)
 | 
				
			||||||
#define PSTATE_M (0xFU)
 | 
					#define PSTATE_M (0xFU)
 | 
				
			||||||
#define PSTATE_nRW (1U << 4)
 | 
					#define PSTATE_nRW (1U << 4)
 | 
				
			||||||
#define PSTATE_F (1U << 6)
 | 
					#define PSTATE_F (1U << 6)
 | 
				
			||||||
@@ -548,17 +558,6 @@ static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
 | 
				
			|||||||
    vfp_set_fpscr(env, new_fpscr);
 | 
					    vfp_set_fpscr(env, new_fpscr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum arm_fprounding {
 | 
					 | 
				
			||||||
    FPROUNDING_TIEEVEN,
 | 
					 | 
				
			||||||
    FPROUNDING_POSINF,
 | 
					 | 
				
			||||||
    FPROUNDING_NEGINF,
 | 
					 | 
				
			||||||
    FPROUNDING_ZERO,
 | 
					 | 
				
			||||||
    FPROUNDING_TIEAWAY,
 | 
					 | 
				
			||||||
    FPROUNDING_ODD
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int arm_rmode_to_sf(int rmode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum arm_cpu_mode {
 | 
					enum arm_cpu_mode {
 | 
				
			||||||
  ARM_CPU_MODE_USR = 0x10,
 | 
					  ARM_CPU_MODE_USR = 0x10,
 | 
				
			||||||
  ARM_CPU_MODE_FIQ = 0x11,
 | 
					  ARM_CPU_MODE_FIQ = 0x11,
 | 
				
			||||||
@@ -572,6 +571,7 @@ enum arm_cpu_mode {
 | 
				
			|||||||
/* VFP system registers.  */
 | 
					/* VFP system registers.  */
 | 
				
			||||||
#define ARM_VFP_FPSID   0
 | 
					#define ARM_VFP_FPSID   0
 | 
				
			||||||
#define ARM_VFP_FPSCR   1
 | 
					#define ARM_VFP_FPSCR   1
 | 
				
			||||||
 | 
					#define ARM_VFP_MVFR2   5
 | 
				
			||||||
#define ARM_VFP_MVFR1   6
 | 
					#define ARM_VFP_MVFR1   6
 | 
				
			||||||
#define ARM_VFP_MVFR0   7
 | 
					#define ARM_VFP_MVFR0   7
 | 
				
			||||||
#define ARM_VFP_FPEXC   8
 | 
					#define ARM_VFP_FPEXC   8
 | 
				
			||||||
@@ -630,6 +630,7 @@ enum arm_features {
 | 
				
			|||||||
    ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
 | 
					    ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
 | 
				
			||||||
    ARM_FEATURE_CBAR, /* has cp15 CBAR */
 | 
					    ARM_FEATURE_CBAR, /* has cp15 CBAR */
 | 
				
			||||||
    ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
 | 
					    ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
 | 
				
			||||||
 | 
					    ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int arm_feature(CPUARMState *env, int feature)
 | 
					static inline int arm_feature(CPUARMState *env, int feature)
 | 
				
			||||||
@@ -763,7 +764,8 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 | 
				
			|||||||
#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
 | 
					#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
 | 
				
			||||||
#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
 | 
					#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
 | 
				
			||||||
#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
 | 
					#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
 | 
				
			||||||
#define ARM_LAST_SPECIAL ARM_CP_CURRENTEL
 | 
					#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
 | 
				
			||||||
 | 
					#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
 | 
				
			||||||
/* Used only as a terminator for ARMCPRegInfo lists */
 | 
					/* Used only as a terminator for ARMCPRegInfo lists */
 | 
				
			||||||
#define ARM_CP_SENTINEL 0xffff
 | 
					#define ARM_CP_SENTINEL 0xffff
 | 
				
			||||||
/* Mask of only the flag bits in a type field */
 | 
					/* Mask of only the flag bits in a type field */
 | 
				
			||||||
@@ -1109,10 +1111,14 @@ static inline int cpu_mmu_index (CPUARMState *env)
 | 
				
			|||||||
#define ARM_TBFLAG_CONDEXEC_MASK    (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
 | 
					#define ARM_TBFLAG_CONDEXEC_MASK    (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
 | 
				
			||||||
#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
 | 
					#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
 | 
				
			||||||
#define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
 | 
					#define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
 | 
				
			||||||
 | 
					#define ARM_TBFLAG_CPACR_FPEN_SHIFT 17
 | 
				
			||||||
 | 
					#define ARM_TBFLAG_CPACR_FPEN_MASK  (1 << ARM_TBFLAG_CPACR_FPEN_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Bit usage when in AArch64 state */
 | 
					/* Bit usage when in AArch64 state */
 | 
				
			||||||
#define ARM_TBFLAG_AA64_EL_SHIFT    0
 | 
					#define ARM_TBFLAG_AA64_EL_SHIFT    0
 | 
				
			||||||
#define ARM_TBFLAG_AA64_EL_MASK     (0x3 << ARM_TBFLAG_AA64_EL_SHIFT)
 | 
					#define ARM_TBFLAG_AA64_EL_MASK     (0x3 << ARM_TBFLAG_AA64_EL_SHIFT)
 | 
				
			||||||
 | 
					#define ARM_TBFLAG_AA64_FPEN_SHIFT  2
 | 
				
			||||||
 | 
					#define ARM_TBFLAG_AA64_FPEN_MASK   (1 << ARM_TBFLAG_AA64_FPEN_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* some convenience accessor macros */
 | 
					/* some convenience accessor macros */
 | 
				
			||||||
#define ARM_TBFLAG_AARCH64_STATE(F) \
 | 
					#define ARM_TBFLAG_AARCH64_STATE(F) \
 | 
				
			||||||
@@ -1131,16 +1137,25 @@ static inline int cpu_mmu_index (CPUARMState *env)
 | 
				
			|||||||
    (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
 | 
					    (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
 | 
				
			||||||
#define ARM_TBFLAG_BSWAP_CODE(F) \
 | 
					#define ARM_TBFLAG_BSWAP_CODE(F) \
 | 
				
			||||||
    (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
 | 
					    (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
 | 
				
			||||||
 | 
					#define ARM_TBFLAG_CPACR_FPEN(F) \
 | 
				
			||||||
 | 
					    (((F) & ARM_TBFLAG_CPACR_FPEN_MASK) >> ARM_TBFLAG_CPACR_FPEN_SHIFT)
 | 
				
			||||||
#define ARM_TBFLAG_AA64_EL(F) \
 | 
					#define ARM_TBFLAG_AA64_EL(F) \
 | 
				
			||||||
    (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT)
 | 
					    (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT)
 | 
				
			||||||
 | 
					#define ARM_TBFLAG_AA64_FPEN(F) \
 | 
				
			||||||
 | 
					    (((F) & ARM_TBFLAG_AA64_FPEN_MASK) >> ARM_TBFLAG_AA64_FPEN_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 | 
					static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 | 
				
			||||||
                                        target_ulong *cs_base, int *flags)
 | 
					                                        target_ulong *cs_base, int *flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int fpen = extract32(env->cp15.c1_coproc, 20, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (is_a64(env)) {
 | 
					    if (is_a64(env)) {
 | 
				
			||||||
        *pc = env->pc;
 | 
					        *pc = env->pc;
 | 
				
			||||||
        *flags = ARM_TBFLAG_AARCH64_STATE_MASK
 | 
					        *flags = ARM_TBFLAG_AARCH64_STATE_MASK
 | 
				
			||||||
            | (arm_current_pl(env) << ARM_TBFLAG_AA64_EL_SHIFT);
 | 
					            | (arm_current_pl(env) << ARM_TBFLAG_AA64_EL_SHIFT);
 | 
				
			||||||
 | 
					        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
 | 
				
			||||||
 | 
					            *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        int privmode;
 | 
					        int privmode;
 | 
				
			||||||
        *pc = env->regs[15];
 | 
					        *pc = env->regs[15];
 | 
				
			||||||
@@ -1157,9 +1172,13 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 | 
				
			|||||||
        if (privmode) {
 | 
					        if (privmode) {
 | 
				
			||||||
            *flags |= ARM_TBFLAG_PRIV_MASK;
 | 
					            *flags |= ARM_TBFLAG_PRIV_MASK;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
 | 
					        if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
 | 
				
			||||||
 | 
					            || arm_el_is_aa64(env, 1)) {
 | 
				
			||||||
            *flags |= ARM_TBFLAG_VFPEN_MASK;
 | 
					            *flags |= ARM_TBFLAG_VFPEN_MASK;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
 | 
				
			||||||
 | 
					            *flags |= ARM_TBFLAG_CPACR_FPEN_MASK;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *cs_base = 0;
 | 
					    *cs_base = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,104 @@ static inline void set_feature(CPUARMState *env, int feature)
 | 
				
			|||||||
    env->features |= 1ULL << feature;
 | 
					    env->features |= 1ULL << feature;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
 | 
					static uint64_t a57_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Number of processors is in [25:24]; otherwise we RAZ */
 | 
				
			||||||
 | 
					    return (smp_cpus - 1) << 24;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const ARMCPRegInfo cortexa57_cp_reginfo[] = {
 | 
				
			||||||
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
 | 
					    { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .readfn = a57_l2ctlr_read,
 | 
				
			||||||
 | 
					      .writefn = arm_cp_write_ignore },
 | 
				
			||||||
 | 
					    { .name = "L2CTLR",
 | 
				
			||||||
 | 
					      .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .readfn = a57_l2ctlr_read,
 | 
				
			||||||
 | 
					      .writefn = arm_cp_write_ignore },
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "L2ECTLR",
 | 
				
			||||||
 | 
					      .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "CPUACTLR",
 | 
				
			||||||
 | 
					      .cp = 15, .opc1 = 0, .crm = 15,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "CPUECTLR",
 | 
				
			||||||
 | 
					      .cp = 15, .opc1 = 1, .crm = 15,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "CPUMERRSR",
 | 
				
			||||||
 | 
					      .cp = 15, .opc1 = 2, .crm = 15,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
 | 
				
			||||||
 | 
					      .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    { .name = "L2MERRSR",
 | 
				
			||||||
 | 
					      .cp = 15, .opc1 = 3, .crm = 15,
 | 
				
			||||||
 | 
					      .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
 | 
				
			||||||
 | 
					    REGINFO_SENTINEL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void aarch64_a57_initfn(Object *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ARMCPU *cpu = ARM_CPU(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_V8);
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_VFP4);
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_NEON);
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_AARCH64);
 | 
				
			||||||
 | 
					    set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
 | 
				
			||||||
 | 
					    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
 | 
				
			||||||
 | 
					    cpu->midr = 0x411fd070;
 | 
				
			||||||
 | 
					    cpu->reset_fpsid = 0x41034070;
 | 
				
			||||||
 | 
					    cpu->mvfr0 = 0x10110222;
 | 
				
			||||||
 | 
					    cpu->mvfr1 = 0x12111111;
 | 
				
			||||||
 | 
					    cpu->mvfr2 = 0x00000043;
 | 
				
			||||||
 | 
					    cpu->ctr = 0x8444c004;
 | 
				
			||||||
 | 
					    cpu->reset_sctlr = 0x00c50838;
 | 
				
			||||||
 | 
					    cpu->id_pfr0 = 0x00000131;
 | 
				
			||||||
 | 
					    cpu->id_pfr1 = 0x00011011;
 | 
				
			||||||
 | 
					    cpu->id_dfr0 = 0x03010066;
 | 
				
			||||||
 | 
					    cpu->id_afr0 = 0x00000000;
 | 
				
			||||||
 | 
					    cpu->id_mmfr0 = 0x10101105;
 | 
				
			||||||
 | 
					    cpu->id_mmfr1 = 0x40000000;
 | 
				
			||||||
 | 
					    cpu->id_mmfr2 = 0x01260000;
 | 
				
			||||||
 | 
					    cpu->id_mmfr3 = 0x02102211;
 | 
				
			||||||
 | 
					    cpu->id_isar0 = 0x02101110;
 | 
				
			||||||
 | 
					    cpu->id_isar1 = 0x13112111;
 | 
				
			||||||
 | 
					    cpu->id_isar2 = 0x21232042;
 | 
				
			||||||
 | 
					    cpu->id_isar3 = 0x01112131;
 | 
				
			||||||
 | 
					    cpu->id_isar4 = 0x00011142;
 | 
				
			||||||
 | 
					    cpu->id_aa64pfr0 = 0x00002222;
 | 
				
			||||||
 | 
					    cpu->id_aa64dfr0 = 0x10305106;
 | 
				
			||||||
 | 
					    cpu->id_aa64isar0 = 0x00010000;
 | 
				
			||||||
 | 
					    cpu->id_aa64mmfr0 = 0x00001124;
 | 
				
			||||||
 | 
					    cpu->clidr = 0x0a200023;
 | 
				
			||||||
 | 
					    cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
 | 
				
			||||||
 | 
					    cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
 | 
				
			||||||
 | 
					    cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
 | 
				
			||||||
 | 
					    cpu->dcz_blocksize = 4; /* 64 bytes */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_USER_ONLY
 | 
					#ifdef CONFIG_USER_ONLY
 | 
				
			||||||
static void aarch64_any_initfn(Object *obj)
 | 
					static void aarch64_any_initfn(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -41,11 +139,11 @@ static void aarch64_any_initfn(Object *obj)
 | 
				
			|||||||
    set_feature(&cpu->env, ARM_FEATURE_VFP4);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_VFP4);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_NEON);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_NEON);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
 | 
					 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_V7MP);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_V7MP);
 | 
				
			||||||
    set_feature(&cpu->env, ARM_FEATURE_AARCH64);
 | 
					    set_feature(&cpu->env, ARM_FEATURE_AARCH64);
 | 
				
			||||||
    cpu->ctr = 0x80030003; /* 32 byte I and D cacheline size, VIPT icache */
 | 
					    cpu->ctr = 0x80030003; /* 32 byte I and D cacheline size, VIPT icache */
 | 
				
			||||||
 | 
					    cpu->dcz_blocksize = 7; /*  512 bytes */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,6 +154,7 @@ typedef struct ARMCPUInfo {
 | 
				
			|||||||
} ARMCPUInfo;
 | 
					} ARMCPUInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const ARMCPUInfo aarch64_cpus[] = {
 | 
					static const ARMCPUInfo aarch64_cpus[] = {
 | 
				
			||||||
 | 
					    { .name = "cortex-a57",         .initfn = aarch64_a57_initfn },
 | 
				
			||||||
#ifdef CONFIG_USER_ONLY
 | 
					#ifdef CONFIG_USER_ONLY
 | 
				
			||||||
    { .name = "any",         .initfn = aarch64_any_initfn },
 | 
					    { .name = "any",         .initfn = aarch64_any_initfn },
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -73,18 +172,22 @@ static void aarch64_cpu_finalizefn(Object *obj)
 | 
				
			|||||||
static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
 | 
					static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ARMCPU *cpu = ARM_CPU(cs);
 | 
					    ARMCPU *cpu = ARM_CPU(cs);
 | 
				
			||||||
    /*
 | 
					    /* It's OK to look at env for the current mode here, because it's
 | 
				
			||||||
     * TODO: this will need updating for system emulation,
 | 
					     * never possible for an AArch64 TB to chain to an AArch32 TB.
 | 
				
			||||||
     * when the core may be in AArch32 mode.
 | 
					     * (Otherwise we would need to use synchronize_from_tb instead.)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    cpu->env.pc = value;
 | 
					    if (is_a64(&cpu->env)) {
 | 
				
			||||||
 | 
					        cpu->env.pc = value;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        cpu->env.regs[15] = value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 | 
					static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUClass *cc = CPU_CLASS(oc);
 | 
					    CPUClass *cc = CPU_CLASS(oc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cc->dump_state = aarch64_cpu_dump_state;
 | 
					    cc->do_interrupt = aarch64_cpu_do_interrupt;
 | 
				
			||||||
    cc->set_pc = aarch64_cpu_set_pc;
 | 
					    cc->set_pc = aarch64_cpu_set_pc;
 | 
				
			||||||
    cc->gdb_read_register = aarch64_cpu_gdb_read_register;
 | 
					    cc->gdb_read_register = aarch64_cpu_gdb_read_register;
 | 
				
			||||||
    cc->gdb_write_register = aarch64_cpu_gdb_write_register;
 | 
					    cc->gdb_write_register = aarch64_cpu_gdb_write_register;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,10 +32,8 @@ int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
 | 
				
			|||||||
    switch (n) {
 | 
					    switch (n) {
 | 
				
			||||||
    case 31:
 | 
					    case 31:
 | 
				
			||||||
        return gdb_get_reg64(mem_buf, env->xregs[31]);
 | 
					        return gdb_get_reg64(mem_buf, env->xregs[31]);
 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case 32:
 | 
					    case 32:
 | 
				
			||||||
        return gdb_get_reg64(mem_buf, env->pc);
 | 
					        return gdb_get_reg64(mem_buf, env->pc);
 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case 33:
 | 
					    case 33:
 | 
				
			||||||
        return gdb_get_reg32(mem_buf, pstate_read(env));
 | 
					        return gdb_get_reg32(mem_buf, pstate_read(env));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@
 | 
				
			|||||||
#include "qemu/host-utils.h"
 | 
					#include "qemu/host-utils.h"
 | 
				
			||||||
#include "sysemu/sysemu.h"
 | 
					#include "sysemu/sysemu.h"
 | 
				
			||||||
#include "qemu/bitops.h"
 | 
					#include "qemu/bitops.h"
 | 
				
			||||||
 | 
					#include "internals.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* C2.4.7 Multiply and divide */
 | 
					/* C2.4.7 Multiply and divide */
 | 
				
			||||||
/* special cases for 0 and LLONG_MIN are mandated by the standard */
 | 
					/* special cases for 0 and LLONG_MIN are mandated by the standard */
 | 
				
			||||||
@@ -436,3 +437,78 @@ float32 HELPER(fcvtx_f64_to_f32)(float64 a, CPUARMState *env)
 | 
				
			|||||||
    set_float_exception_flags(exflags, fpst);
 | 
					    set_float_exception_flags(exflags, fpst);
 | 
				
			||||||
    return r;
 | 
					    return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Handle a CPU exception.  */
 | 
				
			||||||
 | 
					void aarch64_cpu_do_interrupt(CPUState *cs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ARMCPU *cpu = ARM_CPU(cs);
 | 
				
			||||||
 | 
					    CPUARMState *env = &cpu->env;
 | 
				
			||||||
 | 
					    target_ulong addr = env->cp15.c12_vbar;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (arm_current_pl(env) == 0) {
 | 
				
			||||||
 | 
					        if (env->aarch64) {
 | 
				
			||||||
 | 
					            addr += 0x400;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            addr += 0x600;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else if (pstate_read(env) & PSTATE_SP) {
 | 
				
			||||||
 | 
					        addr += 0x200;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    arm_log_exception(cs->exception_index);
 | 
				
			||||||
 | 
					    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_pl(env));
 | 
				
			||||||
 | 
					    if (qemu_loglevel_mask(CPU_LOG_INT)
 | 
				
			||||||
 | 
					        && !excp_is_internal(cs->exception_index)) {
 | 
				
			||||||
 | 
					        qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%" PRIx32 "\n",
 | 
				
			||||||
 | 
					                      env->exception.syndrome);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    env->cp15.esr_el1 = env->exception.syndrome;
 | 
				
			||||||
 | 
					    env->cp15.far_el1 = env->exception.vaddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (cs->exception_index) {
 | 
				
			||||||
 | 
					    case EXCP_PREFETCH_ABORT:
 | 
				
			||||||
 | 
					    case EXCP_DATA_ABORT:
 | 
				
			||||||
 | 
					        qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
 | 
				
			||||||
 | 
					                      env->cp15.far_el1);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EXCP_BKPT:
 | 
				
			||||||
 | 
					    case EXCP_UDEF:
 | 
				
			||||||
 | 
					    case EXCP_SWI:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EXCP_IRQ:
 | 
				
			||||||
 | 
					        addr += 0x80;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EXCP_FIQ:
 | 
				
			||||||
 | 
					        addr += 0x100;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_a64(env)) {
 | 
				
			||||||
 | 
					        env->banked_spsr[0] = pstate_read(env);
 | 
				
			||||||
 | 
					        env->sp_el[arm_current_pl(env)] = env->xregs[31];
 | 
				
			||||||
 | 
					        env->xregs[31] = env->sp_el[1];
 | 
				
			||||||
 | 
					        env->elr_el1 = env->pc;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env->banked_spsr[0] = cpsr_read(env);
 | 
				
			||||||
 | 
					        if (!env->thumb) {
 | 
				
			||||||
 | 
					            env->cp15.esr_el1 |= 1 << 25;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        env->elr_el1 = env->regs[15];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < 15; i++) {
 | 
				
			||||||
 | 
					            env->xregs[i] = env->regs[i];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        env->condexec_bits = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pstate_write(env, PSTATE_DAIF | PSTATE_MODE_EL1h);
 | 
				
			||||||
 | 
					    env->aarch64 = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    env->pc = addr;
 | 
				
			||||||
 | 
					    cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -48,7 +48,8 @@ DEF_HELPER_FLAGS_2(usad8, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
 | 
					DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
 | 
				
			||||||
                   i32, i32, i32, i32)
 | 
					                   i32, i32, i32, i32)
 | 
				
			||||||
DEF_HELPER_2(exception, void, env, i32)
 | 
					DEF_HELPER_2(exception_internal, void, env, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_3(exception_with_syndrome, void, env, i32, i32)
 | 
				
			||||||
DEF_HELPER_1(wfi, void, env)
 | 
					DEF_HELPER_1(wfi, void, env)
 | 
				
			||||||
DEF_HELPER_1(wfe, void, env)
 | 
					DEF_HELPER_1(wfe, void, env)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,13 +59,14 @@ DEF_HELPER_1(cpsr_read, i32, env)
 | 
				
			|||||||
DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 | 
					DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 | 
				
			||||||
DEF_HELPER_2(v7m_mrs, i32, env, i32)
 | 
					DEF_HELPER_2(v7m_mrs, i32, env, i32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_2(access_check_cp_reg, void, env, ptr)
 | 
					DEF_HELPER_3(access_check_cp_reg, void, env, ptr, i32)
 | 
				
			||||||
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
 | 
					DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
 | 
				
			||||||
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
 | 
					DEF_HELPER_2(get_cp_reg, i32, env, ptr)
 | 
				
			||||||
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
 | 
					DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
 | 
				
			||||||
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
 | 
					DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
 | 
					DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_1(exception_return, void, env)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_2(get_r13_banked, i32, env, i32)
 | 
					DEF_HELPER_2(get_r13_banked, i32, env, i32)
 | 
				
			||||||
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
 | 
					DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
 | 
				
			||||||
@@ -514,6 +516,7 @@ DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 | 
					DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 | 
				
			||||||
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 | 
					DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_2(dc_zva, void, env, i64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TARGET_AARCH64
 | 
					#ifdef TARGET_AARCH64
 | 
				
			||||||
#include "helper-a64.h"
 | 
					#include "helper-a64.h"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										267
									
								
								target-arm/internals.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								target-arm/internals.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,267 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * QEMU ARM CPU -- internal functions and types
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (c) 2014 Linaro Ltd
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, see
 | 
				
			||||||
 | 
					 * <http://www.gnu.org/licenses/gpl-2.0.html>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This header defines functions, types, etc which need to be shared
 | 
				
			||||||
 | 
					 * between different source files within target-arm/ but which are
 | 
				
			||||||
 | 
					 * private to it and not required by the rest of QEMU.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TARGET_ARM_INTERNALS_H
 | 
				
			||||||
 | 
					#define TARGET_ARM_INTERNALS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool excp_is_internal(int excp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Return true if this exception number represents a QEMU-internal
 | 
				
			||||||
 | 
					     * exception that will not be passed to the guest.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    return excp == EXCP_INTERRUPT
 | 
				
			||||||
 | 
					        || excp == EXCP_HLT
 | 
				
			||||||
 | 
					        || excp == EXCP_DEBUG
 | 
				
			||||||
 | 
					        || excp == EXCP_HALTED
 | 
				
			||||||
 | 
					        || excp == EXCP_EXCEPTION_EXIT
 | 
				
			||||||
 | 
					        || excp == EXCP_KERNEL_TRAP
 | 
				
			||||||
 | 
					        || excp == EXCP_STREX;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Exception names for debug logging; note that not all of these
 | 
				
			||||||
 | 
					 * precisely correspond to architectural exceptions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const char * const excnames[] = {
 | 
				
			||||||
 | 
					    [EXCP_UDEF] = "Undefined Instruction",
 | 
				
			||||||
 | 
					    [EXCP_SWI] = "SVC",
 | 
				
			||||||
 | 
					    [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
 | 
				
			||||||
 | 
					    [EXCP_DATA_ABORT] = "Data Abort",
 | 
				
			||||||
 | 
					    [EXCP_IRQ] = "IRQ",
 | 
				
			||||||
 | 
					    [EXCP_FIQ] = "FIQ",
 | 
				
			||||||
 | 
					    [EXCP_BKPT] = "Breakpoint",
 | 
				
			||||||
 | 
					    [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
 | 
				
			||||||
 | 
					    [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
 | 
				
			||||||
 | 
					    [EXCP_STREX] = "QEMU intercept of STREX",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void arm_log_exception(int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (qemu_loglevel_mask(CPU_LOG_INT)) {
 | 
				
			||||||
 | 
					        const char *exc = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
 | 
				
			||||||
 | 
					            exc = excnames[idx];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!exc) {
 | 
				
			||||||
 | 
					            exc = "unknown";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Scale factor for generic timers, ie number of ns per tick.
 | 
				
			||||||
 | 
					 * This gives a 62.5MHz timer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define GTIMER_SCALE 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int bank_number(int mode);
 | 
				
			||||||
 | 
					void switch_mode(CPUARMState *, int);
 | 
				
			||||||
 | 
					void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
 | 
				
			||||||
 | 
					void arm_translate_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum arm_fprounding {
 | 
				
			||||||
 | 
					    FPROUNDING_TIEEVEN,
 | 
				
			||||||
 | 
					    FPROUNDING_POSINF,
 | 
				
			||||||
 | 
					    FPROUNDING_NEGINF,
 | 
				
			||||||
 | 
					    FPROUNDING_ZERO,
 | 
				
			||||||
 | 
					    FPROUNDING_TIEAWAY,
 | 
				
			||||||
 | 
					    FPROUNDING_ODD
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int arm_rmode_to_sf(int rmode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void update_spsel(CPUARMState *env, uint32_t imm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Update PSTATE SPSel bit; this requires us to update the
 | 
				
			||||||
 | 
					     * working stack pointer in xregs[31].
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (!((imm ^ env->pstate) & PSTATE_SP)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    env->pstate = deposit32(env->pstate, 0, 1, imm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* EL0 has no access rights to update SPSel, and this code
 | 
				
			||||||
 | 
					     * assumes we are updating SP for EL1 while running as EL1.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    assert(arm_current_pl(env) == 1);
 | 
				
			||||||
 | 
					    if (env->pstate & PSTATE_SP) {
 | 
				
			||||||
 | 
					        /* Switch from using SP_EL0 to using SP_ELx */
 | 
				
			||||||
 | 
					        env->sp_el[0] = env->xregs[31];
 | 
				
			||||||
 | 
					        env->xregs[31] = env->sp_el[1];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        /* Switch from SP_EL0 to SP_ELx */
 | 
				
			||||||
 | 
					        env->sp_el[1] = env->xregs[31];
 | 
				
			||||||
 | 
					        env->xregs[31] = env->sp_el[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Valid Syndrome Register EC field values */
 | 
				
			||||||
 | 
					enum arm_exception_class {
 | 
				
			||||||
 | 
					    EC_UNCATEGORIZED          = 0x00,
 | 
				
			||||||
 | 
					    EC_WFX_TRAP               = 0x01,
 | 
				
			||||||
 | 
					    EC_CP15RTTRAP             = 0x03,
 | 
				
			||||||
 | 
					    EC_CP15RRTTRAP            = 0x04,
 | 
				
			||||||
 | 
					    EC_CP14RTTRAP             = 0x05,
 | 
				
			||||||
 | 
					    EC_CP14DTTRAP             = 0x06,
 | 
				
			||||||
 | 
					    EC_ADVSIMDFPACCESSTRAP    = 0x07,
 | 
				
			||||||
 | 
					    EC_FPIDTRAP               = 0x08,
 | 
				
			||||||
 | 
					    EC_CP14RRTTRAP            = 0x0c,
 | 
				
			||||||
 | 
					    EC_ILLEGALSTATE           = 0x0e,
 | 
				
			||||||
 | 
					    EC_AA32_SVC               = 0x11,
 | 
				
			||||||
 | 
					    EC_AA32_HVC               = 0x12,
 | 
				
			||||||
 | 
					    EC_AA32_SMC               = 0x13,
 | 
				
			||||||
 | 
					    EC_AA64_SVC               = 0x15,
 | 
				
			||||||
 | 
					    EC_AA64_HVC               = 0x16,
 | 
				
			||||||
 | 
					    EC_AA64_SMC               = 0x17,
 | 
				
			||||||
 | 
					    EC_SYSTEMREGISTERTRAP     = 0x18,
 | 
				
			||||||
 | 
					    EC_INSNABORT              = 0x20,
 | 
				
			||||||
 | 
					    EC_INSNABORT_SAME_EL      = 0x21,
 | 
				
			||||||
 | 
					    EC_PCALIGNMENT            = 0x22,
 | 
				
			||||||
 | 
					    EC_DATAABORT              = 0x24,
 | 
				
			||||||
 | 
					    EC_DATAABORT_SAME_EL      = 0x25,
 | 
				
			||||||
 | 
					    EC_SPALIGNMENT            = 0x26,
 | 
				
			||||||
 | 
					    EC_AA32_FPTRAP            = 0x28,
 | 
				
			||||||
 | 
					    EC_AA64_FPTRAP            = 0x2c,
 | 
				
			||||||
 | 
					    EC_SERROR                 = 0x2f,
 | 
				
			||||||
 | 
					    EC_BREAKPOINT             = 0x30,
 | 
				
			||||||
 | 
					    EC_BREAKPOINT_SAME_EL     = 0x31,
 | 
				
			||||||
 | 
					    EC_SOFTWARESTEP           = 0x32,
 | 
				
			||||||
 | 
					    EC_SOFTWARESTEP_SAME_EL   = 0x33,
 | 
				
			||||||
 | 
					    EC_WATCHPOINT             = 0x34,
 | 
				
			||||||
 | 
					    EC_WATCHPOINT_SAME_EL     = 0x35,
 | 
				
			||||||
 | 
					    EC_AA32_BKPT              = 0x38,
 | 
				
			||||||
 | 
					    EC_VECTORCATCH            = 0x3a,
 | 
				
			||||||
 | 
					    EC_AA64_BKPT              = 0x3c,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARM_EL_EC_SHIFT 26
 | 
				
			||||||
 | 
					#define ARM_EL_IL_SHIFT 25
 | 
				
			||||||
 | 
					#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Utility functions for constructing various kinds of syndrome value.
 | 
				
			||||||
 | 
					 * Note that in general we follow the AArch64 syndrome values; in a
 | 
				
			||||||
 | 
					 * few cases the value in HSR for exceptions taken to AArch32 Hyp
 | 
				
			||||||
 | 
					 * mode differs slightly, so if we ever implemented Hyp mode then the
 | 
				
			||||||
 | 
					 * syndrome value would need some massaging on exception entry.
 | 
				
			||||||
 | 
					 * (One example of this is that AArch64 defaults to IL bit set for
 | 
				
			||||||
 | 
					 * exceptions which don't specifically indicate information about the
 | 
				
			||||||
 | 
					 * trapping instruction, whereas AArch32 defaults to IL bit clear.)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline uint32_t syn_uncategorized(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_aa64_svc(uint32_t imm16)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
 | 
				
			||||||
 | 
					                                           int crn, int crm, int rt,
 | 
				
			||||||
 | 
					                                           int isread)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
 | 
				
			||||||
 | 
					        | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
 | 
				
			||||||
 | 
					        | (crm << 1) | isread;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
 | 
				
			||||||
 | 
					                                        int crn, int crm, int rt, int isread,
 | 
				
			||||||
 | 
					                                        bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL)
 | 
				
			||||||
 | 
					        | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
 | 
				
			||||||
 | 
					        | (crn << 10) | (rt << 5) | (crm << 1) | isread;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
 | 
				
			||||||
 | 
					                                        int crn, int crm, int rt, int isread,
 | 
				
			||||||
 | 
					                                        bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL)
 | 
				
			||||||
 | 
					        | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
 | 
				
			||||||
 | 
					        | (crn << 10) | (rt << 5) | (crm << 1) | isread;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
 | 
				
			||||||
 | 
					                                         int rt, int rt2, int isread,
 | 
				
			||||||
 | 
					                                         bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL)
 | 
				
			||||||
 | 
					        | (cv << 24) | (cond << 20) | (opc1 << 16)
 | 
				
			||||||
 | 
					        | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
 | 
				
			||||||
 | 
					                                         int rt, int rt2, int isread,
 | 
				
			||||||
 | 
					                                         bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL)
 | 
				
			||||||
 | 
					        | (cv << 24) | (cond << 20) | (opc1 << 16)
 | 
				
			||||||
 | 
					        | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_thumb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (is_thumb ? 0 : ARM_EL_IL)
 | 
				
			||||||
 | 
					        | (cv << 24) | (cond << 20);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (ea << 9) | (s1ptw << 7) | fsc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t syn_data_abort(int same_el, int ea, int cm, int s1ptw,
 | 
				
			||||||
 | 
					                                      int wnr, int fsc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 | 
				
			||||||
 | 
					        | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -21,6 +21,7 @@
 | 
				
			|||||||
#include "sysemu/kvm.h"
 | 
					#include "sysemu/kvm.h"
 | 
				
			||||||
#include "kvm_arm.h"
 | 
					#include "kvm_arm.h"
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
 | 
					#include "internals.h"
 | 
				
			||||||
#include "hw/arm/arm.h"
 | 
					#include "hw/arm/arm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void set_feature(uint64_t *features, int feature)
 | 
					static inline void set_feature(uint64_t *features, int feature)
 | 
				
			||||||
@@ -294,6 +295,14 @@ typedef struct Reg {
 | 
				
			|||||||
        offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R])      \
 | 
					        offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R])      \
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Like COREREG, but handle fields which are in a uint64_t in CPUARMState. */
 | 
				
			||||||
 | 
					#define COREREG64(KERNELNAME, QEMUFIELD)                     \
 | 
				
			||||||
 | 
					    {                                                        \
 | 
				
			||||||
 | 
					        KVM_REG_ARM | KVM_REG_SIZE_U32 |                     \
 | 
				
			||||||
 | 
					        KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(KERNELNAME), \
 | 
				
			||||||
 | 
					        offsetoflow32(CPUARMState, QEMUFIELD)                \
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const Reg regs[] = {
 | 
					static const Reg regs[] = {
 | 
				
			||||||
    /* R0_usr .. R14_usr */
 | 
					    /* R0_usr .. R14_usr */
 | 
				
			||||||
    COREREG(usr_regs.uregs[0], regs[0]),
 | 
					    COREREG(usr_regs.uregs[0], regs[0]),
 | 
				
			||||||
@@ -314,16 +323,16 @@ static const Reg regs[] = {
 | 
				
			|||||||
    /* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
 | 
					    /* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
 | 
				
			||||||
    COREREG(svc_regs[0], banked_r13[1]),
 | 
					    COREREG(svc_regs[0], banked_r13[1]),
 | 
				
			||||||
    COREREG(svc_regs[1], banked_r14[1]),
 | 
					    COREREG(svc_regs[1], banked_r14[1]),
 | 
				
			||||||
    COREREG(svc_regs[2], banked_spsr[1]),
 | 
					    COREREG64(svc_regs[2], banked_spsr[1]),
 | 
				
			||||||
    COREREG(abt_regs[0], banked_r13[2]),
 | 
					    COREREG(abt_regs[0], banked_r13[2]),
 | 
				
			||||||
    COREREG(abt_regs[1], banked_r14[2]),
 | 
					    COREREG(abt_regs[1], banked_r14[2]),
 | 
				
			||||||
    COREREG(abt_regs[2], banked_spsr[2]),
 | 
					    COREREG64(abt_regs[2], banked_spsr[2]),
 | 
				
			||||||
    COREREG(und_regs[0], banked_r13[3]),
 | 
					    COREREG(und_regs[0], banked_r13[3]),
 | 
				
			||||||
    COREREG(und_regs[1], banked_r14[3]),
 | 
					    COREREG(und_regs[1], banked_r14[3]),
 | 
				
			||||||
    COREREG(und_regs[2], banked_spsr[3]),
 | 
					    COREREG64(und_regs[2], banked_spsr[3]),
 | 
				
			||||||
    COREREG(irq_regs[0], banked_r13[4]),
 | 
					    COREREG(irq_regs[0], banked_r13[4]),
 | 
				
			||||||
    COREREG(irq_regs[1], banked_r14[4]),
 | 
					    COREREG(irq_regs[1], banked_r14[4]),
 | 
				
			||||||
    COREREG(irq_regs[2], banked_spsr[4]),
 | 
					    COREREG64(irq_regs[2], banked_spsr[4]),
 | 
				
			||||||
    /* R8_fiq .. R14_fiq and SPSR_fiq */
 | 
					    /* R8_fiq .. R14_fiq and SPSR_fiq */
 | 
				
			||||||
    COREREG(fiq_regs[0], fiq_regs[0]),
 | 
					    COREREG(fiq_regs[0], fiq_regs[0]),
 | 
				
			||||||
    COREREG(fiq_regs[1], fiq_regs[1]),
 | 
					    COREREG(fiq_regs[1], fiq_regs[1]),
 | 
				
			||||||
@@ -332,7 +341,7 @@ static const Reg regs[] = {
 | 
				
			|||||||
    COREREG(fiq_regs[4], fiq_regs[4]),
 | 
					    COREREG(fiq_regs[4], fiq_regs[4]),
 | 
				
			||||||
    COREREG(fiq_regs[5], banked_r13[5]),
 | 
					    COREREG(fiq_regs[5], banked_r13[5]),
 | 
				
			||||||
    COREREG(fiq_regs[6], banked_r14[5]),
 | 
					    COREREG(fiq_regs[6], banked_r14[5]),
 | 
				
			||||||
    COREREG(fiq_regs[7], banked_spsr[5]),
 | 
					    COREREG64(fiq_regs[7], banked_spsr[5]),
 | 
				
			||||||
    /* R15 */
 | 
					    /* R15 */
 | 
				
			||||||
    COREREG(usr_regs.uregs[15], regs[15]),
 | 
					    COREREG(usr_regs.uregs[15], regs[15]),
 | 
				
			||||||
    /* VFP system registers */
 | 
					    /* VFP system registers */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,8 +121,24 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the
 | 
				
			||||||
 | 
					     * QEMU side we keep the current SP in xregs[31] as well.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (env->pstate & PSTATE_SP) {
 | 
				
			||||||
 | 
					        env->sp_el[1] = env->xregs[31];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env->sp_el[0] = env->xregs[31];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reg.id = AARCH64_CORE_REG(regs.sp);
 | 
					    reg.id = AARCH64_CORE_REG(regs.sp);
 | 
				
			||||||
    reg.addr = (uintptr_t) &env->xregs[31];
 | 
					    reg.addr = (uintptr_t) &env->sp_el[0];
 | 
				
			||||||
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reg.id = AARCH64_CORE_REG(sp_el1);
 | 
				
			||||||
 | 
					    reg.addr = (uintptr_t) &env->sp_el[1];
 | 
				
			||||||
    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
 | 
				
			||||||
    if (ret) {
 | 
					    if (ret) {
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
@@ -144,10 +160,23 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 | 
				
			|||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reg.id = AARCH64_CORE_REG(elr_el1);
 | 
				
			||||||
 | 
					    reg.addr = (uintptr_t) &env->elr_el1;
 | 
				
			||||||
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < KVM_NR_SPSR; i++) {
 | 
				
			||||||
 | 
					        reg.id = AARCH64_CORE_REG(spsr[i]);
 | 
				
			||||||
 | 
					        reg.addr = (uintptr_t) &env->banked_spsr[i - 1];
 | 
				
			||||||
 | 
					        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
 | 
				
			||||||
 | 
					        if (ret) {
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* TODO:
 | 
					    /* TODO:
 | 
				
			||||||
     * SP_EL1
 | 
					 | 
				
			||||||
     * ELR_EL1
 | 
					 | 
				
			||||||
     * SPSR[]
 | 
					 | 
				
			||||||
     * FP state
 | 
					     * FP state
 | 
				
			||||||
     * system registers
 | 
					     * system registers
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -174,7 +203,14 @@ int kvm_arch_get_registers(CPUState *cs)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reg.id = AARCH64_CORE_REG(regs.sp);
 | 
					    reg.id = AARCH64_CORE_REG(regs.sp);
 | 
				
			||||||
    reg.addr = (uintptr_t) &env->xregs[31];
 | 
					    reg.addr = (uintptr_t) &env->sp_el[0];
 | 
				
			||||||
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reg.id = AARCH64_CORE_REG(sp_el1);
 | 
				
			||||||
 | 
					    reg.addr = (uintptr_t) &env->sp_el[1];
 | 
				
			||||||
    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
				
			||||||
    if (ret) {
 | 
					    if (ret) {
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
@@ -188,6 +224,15 @@ int kvm_arch_get_registers(CPUState *cs)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    pstate_write(env, val);
 | 
					    pstate_write(env, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the
 | 
				
			||||||
 | 
					     * QEMU side we keep the current SP in xregs[31] as well.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (env->pstate & PSTATE_SP) {
 | 
				
			||||||
 | 
					        env->xregs[31] = env->sp_el[1];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env->xregs[31] = env->sp_el[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reg.id = AARCH64_CORE_REG(regs.pc);
 | 
					    reg.id = AARCH64_CORE_REG(regs.pc);
 | 
				
			||||||
    reg.addr = (uintptr_t) &env->pc;
 | 
					    reg.addr = (uintptr_t) &env->pc;
 | 
				
			||||||
    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
				
			||||||
@@ -195,6 +240,22 @@ int kvm_arch_get_registers(CPUState *cs)
 | 
				
			|||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reg.id = AARCH64_CORE_REG(elr_el1);
 | 
				
			||||||
 | 
					    reg.addr = (uintptr_t) &env->elr_el1;
 | 
				
			||||||
 | 
					    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < KVM_NR_SPSR; i++) {
 | 
				
			||||||
 | 
					        reg.id = AARCH64_CORE_REG(spsr[i]);
 | 
				
			||||||
 | 
					        reg.addr = (uintptr_t) &env->banked_spsr[i - 1];
 | 
				
			||||||
 | 
					        ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
 | 
				
			||||||
 | 
					        if (ret) {
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* TODO: other registers */
 | 
					    /* TODO: other registers */
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -222,9 +222,9 @@ static int cpu_post_load(void *opaque, int version_id)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const VMStateDescription vmstate_arm_cpu = {
 | 
					const VMStateDescription vmstate_arm_cpu = {
 | 
				
			||||||
    .name = "cpu",
 | 
					    .name = "cpu",
 | 
				
			||||||
    .version_id = 14,
 | 
					    .version_id = 17,
 | 
				
			||||||
    .minimum_version_id = 14,
 | 
					    .minimum_version_id = 17,
 | 
				
			||||||
    .minimum_version_id_old = 14,
 | 
					    .minimum_version_id_old = 17,
 | 
				
			||||||
    .pre_save = cpu_pre_save,
 | 
					    .pre_save = cpu_pre_save,
 | 
				
			||||||
    .post_load = cpu_post_load,
 | 
					    .post_load = cpu_post_load,
 | 
				
			||||||
    .fields = (VMStateField[]) {
 | 
					    .fields = (VMStateField[]) {
 | 
				
			||||||
@@ -238,11 +238,13 @@ const VMStateDescription vmstate_arm_cpu = {
 | 
				
			|||||||
            .offset = 0,
 | 
					            .offset = 0,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        VMSTATE_UINT32(env.spsr, ARMCPU),
 | 
					        VMSTATE_UINT32(env.spsr, ARMCPU),
 | 
				
			||||||
        VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 6),
 | 
					        VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 6),
 | 
				
			||||||
        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
 | 
					        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
 | 
				
			||||||
        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
 | 
					        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
 | 
				
			||||||
        VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
 | 
					        VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
 | 
				
			||||||
        VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
 | 
					        VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
 | 
				
			||||||
 | 
					        VMSTATE_UINT64(env.elr_el1, ARMCPU),
 | 
				
			||||||
 | 
					        VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 2),
 | 
				
			||||||
        /* The length-check must come before the arrays to avoid
 | 
					        /* The length-check must come before the arrays to avoid
 | 
				
			||||||
         * incoming data possibly overflowing the array.
 | 
					         * incoming data possibly overflowing the array.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
@@ -257,6 +259,9 @@ const VMStateDescription vmstate_arm_cpu = {
 | 
				
			|||||||
        VMSTATE_UINT64(env.exclusive_val, ARMCPU),
 | 
					        VMSTATE_UINT64(env.exclusive_val, ARMCPU),
 | 
				
			||||||
        VMSTATE_UINT64(env.exclusive_high, ARMCPU),
 | 
					        VMSTATE_UINT64(env.exclusive_high, ARMCPU),
 | 
				
			||||||
        VMSTATE_UINT64(env.features, ARMCPU),
 | 
					        VMSTATE_UINT64(env.features, ARMCPU),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(env.exception.syndrome, ARMCPU),
 | 
				
			||||||
 | 
					        VMSTATE_UINT32(env.exception.fsr, ARMCPU),
 | 
				
			||||||
 | 
					        VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
 | 
				
			||||||
        VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
 | 
					        VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
 | 
				
			||||||
        VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
 | 
					        VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
 | 
				
			||||||
        VMSTATE_END_OF_LIST()
 | 
					        VMSTATE_END_OF_LIST()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
#include "helper.h"
 | 
					#include "helper.h"
 | 
				
			||||||
 | 
					#include "internals.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SIGNBIT (uint32_t)0x80000000
 | 
					#define SIGNBIT (uint32_t)0x80000000
 | 
				
			||||||
#define SIGNBIT64 ((uint64_t)1 << 63)
 | 
					#define SIGNBIT64 ((uint64_t)1 << 63)
 | 
				
			||||||
@@ -243,14 +244,33 @@ void HELPER(wfe)(CPUARMState *env)
 | 
				
			|||||||
    cpu_loop_exit(cs);
 | 
					    cpu_loop_exit(cs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HELPER(exception)(CPUARMState *env, uint32_t excp)
 | 
					/* Raise an internal-to-QEMU exception. This is limited to only
 | 
				
			||||||
 | 
					 * those EXCP values which are special cases for QEMU to interrupt
 | 
				
			||||||
 | 
					 * execution and not to be used for exceptions which are passed to
 | 
				
			||||||
 | 
					 * the guest (those must all have syndrome information and thus should
 | 
				
			||||||
 | 
					 * use exception_with_syndrome).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUState *cs = CPU(arm_env_get_cpu(env));
 | 
					    CPUState *cs = CPU(arm_env_get_cpu(env));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(excp_is_internal(excp));
 | 
				
			||||||
    cs->exception_index = excp;
 | 
					    cs->exception_index = excp;
 | 
				
			||||||
    cpu_loop_exit(cs);
 | 
					    cpu_loop_exit(cs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Raise an exception with the specified syndrome register value */
 | 
				
			||||||
 | 
					void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
 | 
				
			||||||
 | 
					                                     uint32_t syndrome)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CPUState *cs = CPU(arm_env_get_cpu(env));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(!excp_is_internal(excp));
 | 
				
			||||||
 | 
					    cs->exception_index = excp;
 | 
				
			||||||
 | 
					    env->exception.syndrome = syndrome;
 | 
				
			||||||
 | 
					    cpu_loop_exit(cs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t HELPER(cpsr_read)(CPUARMState *env)
 | 
					uint32_t HELPER(cpsr_read)(CPUARMState *env)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return cpsr_read(env) & ~CPSR_EXEC;
 | 
					    return cpsr_read(env) & ~CPSR_EXEC;
 | 
				
			||||||
@@ -293,17 +313,17 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
 | 
					void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const ARMCPRegInfo *ri = rip;
 | 
					    const ARMCPRegInfo *ri = rip;
 | 
				
			||||||
    switch (ri->accessfn(env, ri)) {
 | 
					    switch (ri->accessfn(env, ri)) {
 | 
				
			||||||
    case CP_ACCESS_OK:
 | 
					    case CP_ACCESS_OK:
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    case CP_ACCESS_TRAP:
 | 
					    case CP_ACCESS_TRAP:
 | 
				
			||||||
 | 
					        env->exception.syndrome = syndrome;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case CP_ACCESS_TRAP_UNCATEGORIZED:
 | 
					    case CP_ACCESS_TRAP_UNCATEGORIZED:
 | 
				
			||||||
        /* These cases will eventually need to generate different
 | 
					        env->exception.syndrome = syn_uncategorized();
 | 
				
			||||||
         * syndrome information.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        g_assert_not_reached();
 | 
					        g_assert_not_reached();
 | 
				
			||||||
@@ -351,7 +371,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    switch (op) {
 | 
					    switch (op) {
 | 
				
			||||||
    case 0x05: /* SPSel */
 | 
					    case 0x05: /* SPSel */
 | 
				
			||||||
        env->pstate = deposit32(env->pstate, 0, 1, imm);
 | 
					        update_spsel(env, imm);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 0x1e: /* DAIFSet */
 | 
					    case 0x1e: /* DAIFSet */
 | 
				
			||||||
        env->daif |= (imm << 6) & PSTATE_DAIF;
 | 
					        env->daif |= (imm << 6) & PSTATE_DAIF;
 | 
				
			||||||
@@ -364,6 +384,66 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HELPER(exception_return)(CPUARMState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t spsr = env->banked_spsr[0];
 | 
				
			||||||
 | 
					    int new_el, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (env->pstate & PSTATE_SP) {
 | 
				
			||||||
 | 
					        env->sp_el[1] = env->xregs[31];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env->sp_el[0] = env->xregs[31];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    env->exclusive_addr = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (spsr & PSTATE_nRW) {
 | 
				
			||||||
 | 
					        env->aarch64 = 0;
 | 
				
			||||||
 | 
					        new_el = 0;
 | 
				
			||||||
 | 
					        env->uncached_cpsr = 0x10;
 | 
				
			||||||
 | 
					        cpsr_write(env, spsr, ~0);
 | 
				
			||||||
 | 
					        for (i = 0; i < 15; i++) {
 | 
				
			||||||
 | 
					            env->regs[i] = env->xregs[i];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        env->regs[15] = env->elr_el1 & ~0x1;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        new_el = extract32(spsr, 2, 2);
 | 
				
			||||||
 | 
					        if (new_el > 1) {
 | 
				
			||||||
 | 
					            /* Return to unimplemented EL */
 | 
				
			||||||
 | 
					            goto illegal_return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (extract32(spsr, 1, 1)) {
 | 
				
			||||||
 | 
					            /* Return with reserved M[1] bit set */
 | 
				
			||||||
 | 
					            goto illegal_return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (new_el == 0 && (spsr & PSTATE_SP)) {
 | 
				
			||||||
 | 
					            /* Return to EL1 with M[0] bit set */
 | 
				
			||||||
 | 
					            goto illegal_return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        env->aarch64 = 1;
 | 
				
			||||||
 | 
					        pstate_write(env, spsr);
 | 
				
			||||||
 | 
					        env->xregs[31] = env->sp_el[new_el];
 | 
				
			||||||
 | 
					        env->pc = env->elr_el1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					illegal_return:
 | 
				
			||||||
 | 
					    /* Illegal return events of various kinds have architecturally
 | 
				
			||||||
 | 
					     * mandated behaviour:
 | 
				
			||||||
 | 
					     * restore NZCV and DAIF from SPSR_ELx
 | 
				
			||||||
 | 
					     * set PSTATE.IL
 | 
				
			||||||
 | 
					     * restore PC from ELR_ELx
 | 
				
			||||||
 | 
					     * no change to exception level, execution state or stack pointer
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    env->pstate |= PSTATE_IL;
 | 
				
			||||||
 | 
					    env->pc = env->elr_el1;
 | 
				
			||||||
 | 
					    spsr &= PSTATE_NZCV | PSTATE_DAIF;
 | 
				
			||||||
 | 
					    spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
 | 
				
			||||||
 | 
					    pstate_write(env, spsr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
 | 
					/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
 | 
				
			||||||
   The only way to do that in TCG is a conditional branch, which clobbers
 | 
					   The only way to do that in TCG is a conditional branch, which clobbers
 | 
				
			||||||
   all our temporaries.  For now implement these as helper functions.  */
 | 
					   all our temporaries.  For now implement these as helper functions.  */
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -25,6 +25,7 @@
 | 
				
			|||||||
#include <inttypes.h>
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
 | 
					#include "internals.h"
 | 
				
			||||||
#include "disas/disas.h"
 | 
					#include "disas/disas.h"
 | 
				
			||||||
#include "tcg-op.h"
 | 
					#include "tcg-op.h"
 | 
				
			||||||
#include "qemu/log.h"
 | 
					#include "qemu/log.h"
 | 
				
			||||||
@@ -182,12 +183,23 @@ static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
 | 
				
			|||||||
/* Set NZCV flags from the high 4 bits of var.  */
 | 
					/* Set NZCV flags from the high 4 bits of var.  */
 | 
				
			||||||
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
 | 
					#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gen_exception(int excp)
 | 
					static void gen_exception_internal(int excp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGv_i32 tmp = tcg_temp_new_i32();
 | 
					    TCGv_i32 tcg_excp = tcg_const_i32(excp);
 | 
				
			||||||
    tcg_gen_movi_i32(tmp, excp);
 | 
					
 | 
				
			||||||
    gen_helper_exception(cpu_env, tmp);
 | 
					    assert(excp_is_internal(excp));
 | 
				
			||||||
    tcg_temp_free_i32(tmp);
 | 
					    gen_helper_exception_internal(cpu_env, tcg_excp);
 | 
				
			||||||
 | 
					    tcg_temp_free_i32(tcg_excp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_exception(int excp, uint32_t syndrome)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TCGv_i32 tcg_excp = tcg_const_i32(excp);
 | 
				
			||||||
 | 
					    TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn);
 | 
				
			||||||
 | 
					    tcg_temp_free_i32(tcg_syn);
 | 
				
			||||||
 | 
					    tcg_temp_free_i32(tcg_excp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 | 
					static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 | 
				
			||||||
@@ -899,6 +911,33 @@ static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
 | 
				
			|||||||
    tcg_gen_movi_i32(cpu_R[15], val);
 | 
					    tcg_gen_movi_i32(cpu_R[15], val);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void
 | 
				
			||||||
 | 
					gen_set_condexec (DisasContext *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (s->condexec_mask) {
 | 
				
			||||||
 | 
					        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
 | 
				
			||||||
 | 
					        TCGv_i32 tmp = tcg_temp_new_i32();
 | 
				
			||||||
 | 
					        tcg_gen_movi_i32(tmp, val);
 | 
				
			||||||
 | 
					        store_cpu_field(tmp, condexec_bits);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gen_set_condexec(s);
 | 
				
			||||||
 | 
					    gen_set_pc_im(s, s->pc - offset);
 | 
				
			||||||
 | 
					    gen_exception_internal(excp);
 | 
				
			||||||
 | 
					    s->is_jmp = DISAS_JUMP;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gen_set_condexec(s);
 | 
				
			||||||
 | 
					    gen_set_pc_im(s, s->pc - offset);
 | 
				
			||||||
 | 
					    gen_exception(excp, syn);
 | 
				
			||||||
 | 
					    s->is_jmp = DISAS_JUMP;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Force a TB lookup after an instruction that changes the CPU state.  */
 | 
					/* Force a TB lookup after an instruction that changes the CPU state.  */
 | 
				
			||||||
static inline void gen_lookup_tb(DisasContext *s)
 | 
					static inline void gen_lookup_tb(DisasContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -2913,14 +2952,25 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
    if (!arm_feature(env, ARM_FEATURE_VFP))
 | 
					    if (!arm_feature(env, ARM_FEATURE_VFP))
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* FIXME: this access check should not take precedence over UNDEF
 | 
				
			||||||
 | 
					     * for invalid encodings; we will generate incorrect syndrome information
 | 
				
			||||||
 | 
					     * for attempts to execute invalid vfp/neon encodings with FP disabled.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (!s->cpacr_fpen) {
 | 
				
			||||||
 | 
					        gen_exception_insn(s, 4, EXCP_UDEF,
 | 
				
			||||||
 | 
					                           syn_fp_access_trap(1, 0xe, s->thumb));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s->vfp_enabled) {
 | 
					    if (!s->vfp_enabled) {
 | 
				
			||||||
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
 | 
					        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
 | 
				
			||||||
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
 | 
					        if ((insn & 0x0fe00fff) != 0x0ee00a10)
 | 
				
			||||||
            return 1;
 | 
					            return 1;
 | 
				
			||||||
        rn = (insn >> 16) & 0xf;
 | 
					        rn = (insn >> 16) & 0xf;
 | 
				
			||||||
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
 | 
					        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
 | 
				
			||||||
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
 | 
					            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
 | 
				
			||||||
            return 1;
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (extract32(insn, 28, 4) == 0xf) {
 | 
					    if (extract32(insn, 28, 4) == 0xf) {
 | 
				
			||||||
@@ -3066,6 +3116,11 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
 | 
					                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case ARM_VFP_MVFR2:
 | 
				
			||||||
 | 
					                            if (!arm_feature(env, ARM_FEATURE_V8)) {
 | 
				
			||||||
 | 
					                                return 1;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            /* fall through */
 | 
				
			||||||
                        case ARM_VFP_MVFR0:
 | 
					                        case ARM_VFP_MVFR0:
 | 
				
			||||||
                        case ARM_VFP_MVFR1:
 | 
					                        case ARM_VFP_MVFR1:
 | 
				
			||||||
                            if (IS_USER(s)
 | 
					                            if (IS_USER(s)
 | 
				
			||||||
@@ -3912,25 +3967,6 @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
 | 
				
			|||||||
    s->is_jmp = DISAS_UPDATE;
 | 
					    s->is_jmp = DISAS_UPDATE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void
 | 
					 | 
				
			||||||
gen_set_condexec (DisasContext *s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (s->condexec_mask) {
 | 
					 | 
				
			||||||
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
 | 
					 | 
				
			||||||
        TCGv_i32 tmp = tcg_temp_new_i32();
 | 
					 | 
				
			||||||
        tcg_gen_movi_i32(tmp, val);
 | 
					 | 
				
			||||||
        store_cpu_field(tmp, condexec_bits);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void gen_exception_insn(DisasContext *s, int offset, int excp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_set_condexec(s);
 | 
					 | 
				
			||||||
    gen_set_pc_im(s, s->pc - offset);
 | 
					 | 
				
			||||||
    gen_exception(excp);
 | 
					 | 
				
			||||||
    s->is_jmp = DISAS_JUMP;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void gen_nop_hint(DisasContext *s, int val)
 | 
					static void gen_nop_hint(DisasContext *s, int val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (val) {
 | 
					    switch (val) {
 | 
				
			||||||
@@ -4212,6 +4248,16 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
    TCGv_i32 tmp2;
 | 
					    TCGv_i32 tmp2;
 | 
				
			||||||
    TCGv_i64 tmp64;
 | 
					    TCGv_i64 tmp64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* FIXME: this access check should not take precedence over UNDEF
 | 
				
			||||||
 | 
					     * for invalid encodings; we will generate incorrect syndrome information
 | 
				
			||||||
 | 
					     * for attempts to execute invalid vfp/neon encodings with FP disabled.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (!s->cpacr_fpen) {
 | 
				
			||||||
 | 
					        gen_exception_insn(s, 4, EXCP_UDEF,
 | 
				
			||||||
 | 
					                           syn_fp_access_trap(1, 0xe, s->thumb));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s->vfp_enabled)
 | 
					    if (!s->vfp_enabled)
 | 
				
			||||||
      return 1;
 | 
					      return 1;
 | 
				
			||||||
    VFP_DREG_D(rd, insn);
 | 
					    VFP_DREG_D(rd, insn);
 | 
				
			||||||
@@ -4934,6 +4980,16 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
 | 
				
			|||||||
    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
 | 
					    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
 | 
				
			||||||
    TCGv_i64 tmp64;
 | 
					    TCGv_i64 tmp64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* FIXME: this access check should not take precedence over UNDEF
 | 
				
			||||||
 | 
					     * for invalid encodings; we will generate incorrect syndrome information
 | 
				
			||||||
 | 
					     * for attempts to execute invalid vfp/neon encodings with FP disabled.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (!s->cpacr_fpen) {
 | 
				
			||||||
 | 
					        gen_exception_insn(s, 4, EXCP_UDEF,
 | 
				
			||||||
 | 
					                           syn_fp_access_trap(1, 0xe, s->thumb));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s->vfp_enabled)
 | 
					    if (!s->vfp_enabled)
 | 
				
			||||||
      return 1;
 | 
					      return 1;
 | 
				
			||||||
    q = (insn & (1 << 6)) != 0;
 | 
					    q = (insn & (1 << 6)) != 0;
 | 
				
			||||||
@@ -6861,10 +6917,53 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
             * runtime; this may result in an exception.
 | 
					             * runtime; this may result in an exception.
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            TCGv_ptr tmpptr;
 | 
					            TCGv_ptr tmpptr;
 | 
				
			||||||
 | 
					            TCGv_i32 tcg_syn;
 | 
				
			||||||
 | 
					            uint32_t syndrome;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Note that since we are an implementation which takes an
 | 
				
			||||||
 | 
					             * exception on a trapped conditional instruction only if the
 | 
				
			||||||
 | 
					             * instruction passes its condition code check, we can take
 | 
				
			||||||
 | 
					             * advantage of the clause in the ARM ARM that allows us to set
 | 
				
			||||||
 | 
					             * the COND field in the instruction to 0xE in all cases.
 | 
				
			||||||
 | 
					             * We could fish the actual condition out of the insn (ARM)
 | 
				
			||||||
 | 
					             * or the condexec bits (Thumb) but it isn't necessary.
 | 
				
			||||||
 | 
					             */
 | 
				
			||||||
 | 
					            switch (cpnum) {
 | 
				
			||||||
 | 
					            case 14:
 | 
				
			||||||
 | 
					                if (is64) {
 | 
				
			||||||
 | 
					                    syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
 | 
				
			||||||
 | 
					                                                 isread, s->thumb);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
 | 
				
			||||||
 | 
					                                                rt, isread, s->thumb);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 15:
 | 
				
			||||||
 | 
					                if (is64) {
 | 
				
			||||||
 | 
					                    syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
 | 
				
			||||||
 | 
					                                                 isread, s->thumb);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
 | 
				
			||||||
 | 
					                                                rt, isread, s->thumb);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                /* ARMv8 defines that only coprocessors 14 and 15 exist,
 | 
				
			||||||
 | 
					                 * so this can only happen if this is an ARMv7 or earlier CPU,
 | 
				
			||||||
 | 
					                 * in which case the syndrome information won't actually be
 | 
				
			||||||
 | 
					                 * guest visible.
 | 
				
			||||||
 | 
					                 */
 | 
				
			||||||
 | 
					                assert(!arm_feature(env, ARM_FEATURE_V8));
 | 
				
			||||||
 | 
					                syndrome = syn_uncategorized();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            gen_set_pc_im(s, s->pc);
 | 
					            gen_set_pc_im(s, s->pc);
 | 
				
			||||||
            tmpptr = tcg_const_ptr(ri);
 | 
					            tmpptr = tcg_const_ptr(ri);
 | 
				
			||||||
            gen_helper_access_check_cp_reg(cpu_env, tmpptr);
 | 
					            tcg_syn = tcg_const_i32(syndrome);
 | 
				
			||||||
 | 
					            gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
 | 
				
			||||||
            tcg_temp_free_ptr(tmpptr);
 | 
					            tcg_temp_free_ptr(tmpptr);
 | 
				
			||||||
 | 
					            tcg_temp_free_i32(tcg_syn);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Handle special cases first */
 | 
					        /* Handle special cases first */
 | 
				
			||||||
@@ -7116,7 +7215,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 | 
				
			|||||||
    tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
 | 
					    tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
 | 
				
			||||||
    tcg_gen_movi_i32(cpu_exclusive_info,
 | 
					    tcg_gen_movi_i32(cpu_exclusive_info,
 | 
				
			||||||
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
 | 
					                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
 | 
				
			||||||
    gen_exception_insn(s, 4, EXCP_STREX);
 | 
					    gen_exception_internal_insn(s, 4, EXCP_STREX);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 | 
					static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 | 
				
			||||||
@@ -7626,6 +7725,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 | 
				
			|||||||
            store_reg(s, rd, tmp);
 | 
					            store_reg(s, rd, tmp);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case 7:
 | 
					        case 7:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
 | 
				
			||||||
            /* SMC instruction (op1 == 3)
 | 
					            /* SMC instruction (op1 == 3)
 | 
				
			||||||
               and undefined instructions (op1 == 0 || op1 == 2)
 | 
					               and undefined instructions (op1 == 0 || op1 == 2)
 | 
				
			||||||
               will trap */
 | 
					               will trap */
 | 
				
			||||||
@@ -7634,8 +7735,9 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            /* bkpt */
 | 
					            /* bkpt */
 | 
				
			||||||
            ARCH(5);
 | 
					            ARCH(5);
 | 
				
			||||||
            gen_exception_insn(s, 4, EXCP_BKPT);
 | 
					            gen_exception_insn(s, 4, EXCP_BKPT, syn_aa32_bkpt(imm16, false));
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        case 0x8: /* signed multiply */
 | 
					        case 0x8: /* signed multiply */
 | 
				
			||||||
        case 0xa:
 | 
					        case 0xa:
 | 
				
			||||||
        case 0xc:
 | 
					        case 0xc:
 | 
				
			||||||
@@ -8328,27 +8430,39 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 | 
				
			|||||||
                        if (insn & (1 << 5))
 | 
					                        if (insn & (1 << 5))
 | 
				
			||||||
                            gen_swap_half(tmp2);
 | 
					                            gen_swap_half(tmp2);
 | 
				
			||||||
                        gen_smul_dual(tmp, tmp2);
 | 
					                        gen_smul_dual(tmp, tmp2);
 | 
				
			||||||
                        if (insn & (1 << 6)) {
 | 
					 | 
				
			||||||
                            /* This subtraction cannot overflow. */
 | 
					 | 
				
			||||||
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            /* This addition cannot overflow 32 bits;
 | 
					 | 
				
			||||||
                             * however it may overflow considered as a signed
 | 
					 | 
				
			||||||
                             * operation, in which case we must set the Q flag.
 | 
					 | 
				
			||||||
                             */
 | 
					 | 
				
			||||||
                            gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        tcg_temp_free_i32(tmp2);
 | 
					 | 
				
			||||||
                        if (insn & (1 << 22)) {
 | 
					                        if (insn & (1 << 22)) {
 | 
				
			||||||
                            /* smlald, smlsld */
 | 
					                            /* smlald, smlsld */
 | 
				
			||||||
 | 
					                            TCGv_i64 tmp64_2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            tmp64 = tcg_temp_new_i64();
 | 
					                            tmp64 = tcg_temp_new_i64();
 | 
				
			||||||
 | 
					                            tmp64_2 = tcg_temp_new_i64();
 | 
				
			||||||
                            tcg_gen_ext_i32_i64(tmp64, tmp);
 | 
					                            tcg_gen_ext_i32_i64(tmp64, tmp);
 | 
				
			||||||
 | 
					                            tcg_gen_ext_i32_i64(tmp64_2, tmp2);
 | 
				
			||||||
                            tcg_temp_free_i32(tmp);
 | 
					                            tcg_temp_free_i32(tmp);
 | 
				
			||||||
 | 
					                            tcg_temp_free_i32(tmp2);
 | 
				
			||||||
 | 
					                            if (insn & (1 << 6)) {
 | 
				
			||||||
 | 
					                                tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            tcg_temp_free_i64(tmp64_2);
 | 
				
			||||||
                            gen_addq(s, tmp64, rd, rn);
 | 
					                            gen_addq(s, tmp64, rd, rn);
 | 
				
			||||||
                            gen_storeq_reg(s, rd, rn, tmp64);
 | 
					                            gen_storeq_reg(s, rd, rn, tmp64);
 | 
				
			||||||
                            tcg_temp_free_i64(tmp64);
 | 
					                            tcg_temp_free_i64(tmp64);
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            /* smuad, smusd, smlad, smlsd */
 | 
					                            /* smuad, smusd, smlad, smlsd */
 | 
				
			||||||
 | 
					                            if (insn & (1 << 6)) {
 | 
				
			||||||
 | 
					                                /* This subtraction cannot overflow. */
 | 
				
			||||||
 | 
					                                tcg_gen_sub_i32(tmp, tmp, tmp2);
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                /* This addition cannot overflow 32 bits;
 | 
				
			||||||
 | 
					                                 * however it may overflow considered as a
 | 
				
			||||||
 | 
					                                 * signed operation, in which case we must set
 | 
				
			||||||
 | 
					                                 * the Q flag.
 | 
				
			||||||
 | 
					                                 */
 | 
				
			||||||
 | 
					                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            tcg_temp_free_i32(tmp2);
 | 
				
			||||||
                            if (rd != 15)
 | 
					                            if (rd != 15)
 | 
				
			||||||
                              {
 | 
					                              {
 | 
				
			||||||
                                tmp2 = load_reg(s, rd);
 | 
					                                tmp2 = load_reg(s, rd);
 | 
				
			||||||
@@ -8642,11 +8756,12 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 | 
				
			|||||||
        case 0xf:
 | 
					        case 0xf:
 | 
				
			||||||
            /* swi */
 | 
					            /* swi */
 | 
				
			||||||
            gen_set_pc_im(s, s->pc);
 | 
					            gen_set_pc_im(s, s->pc);
 | 
				
			||||||
 | 
					            s->svc_imm = extract32(insn, 0, 24);
 | 
				
			||||||
            s->is_jmp = DISAS_SWI;
 | 
					            s->is_jmp = DISAS_SWI;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
        illegal_op:
 | 
					        illegal_op:
 | 
				
			||||||
            gen_exception_insn(s, 4, EXCP_UDEF);
 | 
					            gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -10457,9 +10572,12 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 0xe: /* bkpt */
 | 
					        case 0xe: /* bkpt */
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int imm8 = extract32(insn, 0, 8);
 | 
				
			||||||
            ARCH(5);
 | 
					            ARCH(5);
 | 
				
			||||||
            gen_exception_insn(s, 2, EXCP_BKPT);
 | 
					            gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 0xa: /* rev */
 | 
					        case 0xa: /* rev */
 | 
				
			||||||
            ARCH(6);
 | 
					            ARCH(6);
 | 
				
			||||||
@@ -10576,6 +10694,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 | 
				
			|||||||
        if (cond == 0xf) {
 | 
					        if (cond == 0xf) {
 | 
				
			||||||
            /* swi */
 | 
					            /* swi */
 | 
				
			||||||
            gen_set_pc_im(s, s->pc);
 | 
					            gen_set_pc_im(s, s->pc);
 | 
				
			||||||
 | 
					            s->svc_imm = extract32(insn, 0, 8);
 | 
				
			||||||
            s->is_jmp = DISAS_SWI;
 | 
					            s->is_jmp = DISAS_SWI;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -10611,11 +10730,11 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
undef32:
 | 
					undef32:
 | 
				
			||||||
    gen_exception_insn(s, 4, EXCP_UDEF);
 | 
					    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
illegal_op:
 | 
					illegal_op:
 | 
				
			||||||
undef:
 | 
					undef:
 | 
				
			||||||
    gen_exception_insn(s, 2, EXCP_UDEF);
 | 
					    gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
 | 
					/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
 | 
				
			||||||
@@ -10665,6 +10784,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
 | 
					    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
 | 
				
			||||||
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
 | 
					    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
 | 
				
			||||||
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
 | 
					    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
 | 
				
			||||||
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
 | 
					    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
 | 
				
			||||||
@@ -10736,7 +10856,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
        if (dc->pc >= 0xffff0000) {
 | 
					        if (dc->pc >= 0xffff0000) {
 | 
				
			||||||
            /* We always get here via a jump, so know we are not in a
 | 
					            /* We always get here via a jump, so know we are not in a
 | 
				
			||||||
               conditional execution block.  */
 | 
					               conditional execution block.  */
 | 
				
			||||||
            gen_exception(EXCP_KERNEL_TRAP);
 | 
					            gen_exception_internal(EXCP_KERNEL_TRAP);
 | 
				
			||||||
            dc->is_jmp = DISAS_UPDATE;
 | 
					            dc->is_jmp = DISAS_UPDATE;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -10744,7 +10864,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
 | 
					        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
 | 
				
			||||||
            /* We always get here via a jump, so know we are not in a
 | 
					            /* We always get here via a jump, so know we are not in a
 | 
				
			||||||
               conditional execution block.  */
 | 
					               conditional execution block.  */
 | 
				
			||||||
            gen_exception(EXCP_EXCEPTION_EXIT);
 | 
					            gen_exception_internal(EXCP_EXCEPTION_EXIT);
 | 
				
			||||||
            dc->is_jmp = DISAS_UPDATE;
 | 
					            dc->is_jmp = DISAS_UPDATE;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -10753,7 +10873,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
 | 
					        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
 | 
				
			||||||
            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
 | 
					            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
 | 
				
			||||||
                if (bp->pc == dc->pc) {
 | 
					                if (bp->pc == dc->pc) {
 | 
				
			||||||
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
 | 
					                    gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
 | 
				
			||||||
                    /* Advance PC so that clearing the breakpoint will
 | 
					                    /* Advance PC so that clearing the breakpoint will
 | 
				
			||||||
                       invalidate this TB.  */
 | 
					                       invalidate this TB.  */
 | 
				
			||||||
                    dc->pc += 2;
 | 
					                    dc->pc += 2;
 | 
				
			||||||
@@ -10833,9 +10953,9 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
        if (dc->condjmp) {
 | 
					        if (dc->condjmp) {
 | 
				
			||||||
            gen_set_condexec(dc);
 | 
					            gen_set_condexec(dc);
 | 
				
			||||||
            if (dc->is_jmp == DISAS_SWI) {
 | 
					            if (dc->is_jmp == DISAS_SWI) {
 | 
				
			||||||
                gen_exception(EXCP_SWI);
 | 
					                gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                gen_exception(EXCP_DEBUG);
 | 
					                gen_exception_internal(EXCP_DEBUG);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            gen_set_label(dc->condlabel);
 | 
					            gen_set_label(dc->condlabel);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -10845,11 +10965,11 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        gen_set_condexec(dc);
 | 
					        gen_set_condexec(dc);
 | 
				
			||||||
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
 | 
					        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
 | 
				
			||||||
            gen_exception(EXCP_SWI);
 | 
					            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            /* FIXME: Single stepping a WFI insn will not halt
 | 
					            /* FIXME: Single stepping a WFI insn will not halt
 | 
				
			||||||
               the CPU.  */
 | 
					               the CPU.  */
 | 
				
			||||||
            gen_exception(EXCP_DEBUG);
 | 
					            gen_exception_internal(EXCP_DEBUG);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* While branches must always occur at the end of an IT block,
 | 
					        /* While branches must always occur at the end of an IT block,
 | 
				
			||||||
@@ -10881,7 +11001,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
				
			|||||||
            gen_helper_wfe(cpu_env);
 | 
					            gen_helper_wfe(cpu_env);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case DISAS_SWI:
 | 
					        case DISAS_SWI:
 | 
				
			||||||
            gen_exception(EXCP_SWI);
 | 
					            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dc->condjmp) {
 | 
					        if (dc->condjmp) {
 | 
				
			||||||
@@ -10939,6 +11059,11 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 | 
				
			|||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    uint32_t psr;
 | 
					    uint32_t psr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_a64(env)) {
 | 
				
			||||||
 | 
					        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(i=0;i<16;i++) {
 | 
					    for(i=0;i<16;i++) {
 | 
				
			||||||
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
 | 
					        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
 | 
				
			||||||
        if ((i % 4) == 3)
 | 
					        if ((i % 4) == 3)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,13 +20,26 @@ typedef struct DisasContext {
 | 
				
			|||||||
#if !defined(CONFIG_USER_ONLY)
 | 
					#if !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
    int user;
 | 
					    int user;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    int vfp_enabled;
 | 
					    bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
 | 
				
			||||||
 | 
					    bool vfp_enabled; /* FP enabled via FPSCR.EN */
 | 
				
			||||||
    int vec_len;
 | 
					    int vec_len;
 | 
				
			||||||
    int vec_stride;
 | 
					    int vec_stride;
 | 
				
			||||||
 | 
					    /* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
 | 
				
			||||||
 | 
					     * so that top level loop can generate correct syndrome information.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    uint32_t svc_imm;
 | 
				
			||||||
    int aarch64;
 | 
					    int aarch64;
 | 
				
			||||||
    int current_pl;
 | 
					    int current_pl;
 | 
				
			||||||
    GHashTable *cp_regs;
 | 
					    GHashTable *cp_regs;
 | 
				
			||||||
    uint64_t features; /* CPU features bits */
 | 
					    uint64_t features; /* CPU features bits */
 | 
				
			||||||
 | 
					    /* Because unallocated encodings generate different exception syndrome
 | 
				
			||||||
 | 
					     * information from traps due to FP being disabled, we can't do a single
 | 
				
			||||||
 | 
					     * "is fp access disabled" check at a high level in the decode tree.
 | 
				
			||||||
 | 
					     * To help in catching bugs where the access check was forgotten in some
 | 
				
			||||||
 | 
					     * code path, we set this flag when the access check is done, and assert
 | 
				
			||||||
 | 
					     * that it is set at the point where we actually touch the FP regs.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    bool fp_access_checked;
 | 
				
			||||||
#define TMP_A64_MAX 16
 | 
					#define TMP_A64_MAX 16
 | 
				
			||||||
    int tmp_a64_count;
 | 
					    int tmp_a64_count;
 | 
				
			||||||
    TCGv_i64 tmp_a64[TMP_A64_MAX];
 | 
					    TCGv_i64 tmp_a64[TMP_A64_MAX];
 | 
				
			||||||
@@ -59,6 +72,8 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
 | 
				
			|||||||
                                        TranslationBlock *tb,
 | 
					                                        TranslationBlock *tb,
 | 
				
			||||||
                                        bool search_pc);
 | 
					                                        bool search_pc);
 | 
				
			||||||
void gen_a64_set_pc_im(uint64_t val);
 | 
					void gen_a64_set_pc_im(uint64_t val);
 | 
				
			||||||
 | 
					void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
 | 
				
			||||||
 | 
					                            fprintf_function cpu_fprintf, int flags);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline void a64_translate_init(void)
 | 
					static inline void a64_translate_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -73,6 +88,12 @@ static inline void gen_intermediate_code_internal_a64(ARMCPU *cpu,
 | 
				
			|||||||
static inline void gen_a64_set_pc_im(uint64_t val)
 | 
					static inline void gen_a64_set_pc_im(uint64_t val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
 | 
				
			||||||
 | 
					                                          fprintf_function cpu_fprintf,
 | 
				
			||||||
 | 
					                                          int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void arm_gen_test_cc(int cc, int label);
 | 
					void arm_gen_test_cc(int cc, int label);
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -17,17 +17,23 @@
 | 
				
			|||||||
#undef TCG_TARGET_STACK_GROWSUP
 | 
					#undef TCG_TARGET_STACK_GROWSUP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3, TCG_REG_X4,
 | 
					    TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3,
 | 
				
			||||||
    TCG_REG_X5, TCG_REG_X6, TCG_REG_X7, TCG_REG_X8, TCG_REG_X9,
 | 
					    TCG_REG_X4, TCG_REG_X5, TCG_REG_X6, TCG_REG_X7,
 | 
				
			||||||
    TCG_REG_X10, TCG_REG_X11, TCG_REG_X12, TCG_REG_X13, TCG_REG_X14,
 | 
					    TCG_REG_X8, TCG_REG_X9, TCG_REG_X10, TCG_REG_X11,
 | 
				
			||||||
    TCG_REG_X15, TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19,
 | 
					    TCG_REG_X12, TCG_REG_X13, TCG_REG_X14, TCG_REG_X15,
 | 
				
			||||||
    TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23, TCG_REG_X24,
 | 
					    TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19,
 | 
				
			||||||
    TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, TCG_REG_X28,
 | 
					    TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23,
 | 
				
			||||||
    TCG_REG_FP,  /* frame pointer */
 | 
					    TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27,
 | 
				
			||||||
    TCG_REG_LR, /* link register */
 | 
					    TCG_REG_X28, TCG_REG_X29, TCG_REG_X30,
 | 
				
			||||||
    TCG_REG_SP,  /* stack pointer or zero register */
 | 
					
 | 
				
			||||||
    TCG_REG_XZR = TCG_REG_SP /* same register number */
 | 
					    /* X31 is either the stack pointer or zero, depending on context.  */
 | 
				
			||||||
    /* program counter is not directly accessible! */
 | 
					    TCG_REG_SP = 31,
 | 
				
			||||||
 | 
					    TCG_REG_XZR = 31,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Aliases.  */
 | 
				
			||||||
 | 
					    TCG_REG_FP = TCG_REG_X29,
 | 
				
			||||||
 | 
					    TCG_REG_LR = TCG_REG_X30,
 | 
				
			||||||
 | 
					    TCG_AREG0  = TCG_REG_X19,
 | 
				
			||||||
} TCGReg;
 | 
					} TCGReg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TCG_TARGET_NB_REGS 32
 | 
					#define TCG_TARGET_NB_REGS 32
 | 
				
			||||||
@@ -92,11 +98,7 @@ typedef enum {
 | 
				
			|||||||
#define TCG_TARGET_HAS_muluh_i64        1
 | 
					#define TCG_TARGET_HAS_muluh_i64        1
 | 
				
			||||||
#define TCG_TARGET_HAS_mulsh_i64        1
 | 
					#define TCG_TARGET_HAS_mulsh_i64        1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					#define TCG_TARGET_HAS_new_ldst         1
 | 
				
			||||||
    TCG_AREG0 = TCG_REG_X19,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TCG_TARGET_HAS_new_ldst         0
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 | 
					static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -69,10 +69,14 @@ _use_sample_img empty.bochs.bz2
 | 
				
			|||||||
poke_file "$TEST_IMG" "$disk_size_offset" "\x00\xc0\x0f\x00\x00\x00\x00\x7f"
 | 
					poke_file "$TEST_IMG" "$disk_size_offset" "\x00\xc0\x0f\x00\x00\x00\x00\x7f"
 | 
				
			||||||
{ $QEMU_IO -c "read 2T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 | 
					{ $QEMU_IO -c "read 2T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_use_sample_img empty.bochs.bz2
 | 
				
			||||||
 | 
					poke_file "$TEST_IMG" "$catalog_size_offset" "\x10\x00\x00\x00"
 | 
				
			||||||
 | 
					{ $QEMU_IO -c "read 0xfbe00 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo
 | 
					echo
 | 
				
			||||||
echo "== Negative extent size =="
 | 
					echo "== Negative extent size =="
 | 
				
			||||||
_use_sample_img empty.bochs.bz2
 | 
					_use_sample_img empty.bochs.bz2
 | 
				
			||||||
poke_file "$TEST_IMG" "$extent_size_offset" "\xff\xff\xff\xff"
 | 
					poke_file "$TEST_IMG" "$extent_size_offset" "\x00\x00\x00\x80"
 | 
				
			||||||
{ $QEMU_IO -c "read 768k 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 | 
					{ $QEMU_IO -c "read 768k 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo
 | 
					echo
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,12 +15,14 @@ no file open, try 'help open'
 | 
				
			|||||||
== Too small catalog bitmap for image size ==
 | 
					== Too small catalog bitmap for image size ==
 | 
				
			||||||
qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
 | 
					qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
 | 
				
			||||||
no file open, try 'help open'
 | 
					no file open, try 'help open'
 | 
				
			||||||
 | 
					qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
 | 
				
			||||||
 | 
					no file open, try 'help open'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
== Negative extent size ==
 | 
					== Negative extent size ==
 | 
				
			||||||
qemu-io: can't open device TEST_DIR/empty.bochs: Extent size 4294967295 is too large
 | 
					qemu-io: can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large
 | 
				
			||||||
no file open, try 'help open'
 | 
					no file open, try 'help open'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
== Zero extent size ==
 | 
					== Zero extent size ==
 | 
				
			||||||
qemu-io: can't open device TEST_DIR/empty.bochs: Extent size may not be zero
 | 
					qemu-io: can't open device TEST_DIR/empty.bochs: Extent size must be at least 512
 | 
				
			||||||
no file open, try 'help open'
 | 
					no file open, try 'help open'
 | 
				
			||||||
*** done
 | 
					*** done
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								trace-events
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								trace-events
									
									
									
									
									
								
							@@ -433,6 +433,27 @@ usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag) "dev %d, tag 0
 | 
				
			|||||||
usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) "dev %d, tag 0x%x, lun %d"
 | 
					usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) "dev %d, tag 0x%x, lun %d"
 | 
				
			||||||
usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) "dev %d, tag 0x%x, function 0x%x"
 | 
					usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) "dev %d, tag 0x%x, function 0x%x"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# hw/usb/dev-mtp.c
 | 
				
			||||||
 | 
					usb_mtp_reset(int addr) "dev %d"
 | 
				
			||||||
 | 
					usb_mtp_command(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x, 0x%x, 0x%x, 0x%x"
 | 
				
			||||||
 | 
					usb_mtp_success(int dev, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, trans 0x%x, args 0x%x, 0x%x"
 | 
				
			||||||
 | 
					usb_mtp_error(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x"
 | 
				
			||||||
 | 
					usb_mtp_data_in(int dev, uint32_t trans, uint32_t len) "dev %d, trans 0x%x, len %d"
 | 
				
			||||||
 | 
					usb_mtp_data_out(int dev, uint32_t trans, uint32_t len) "dev %d, trans 0x%x, len %d"
 | 
				
			||||||
 | 
					usb_mtp_xfer(int dev, uint32_t ep, uint32_t dlen, uint32_t plen) "dev %d, ep %d, %d/%d"
 | 
				
			||||||
 | 
					usb_mtp_nak(int dev, uint32_t ep) "dev %d, ep %d"
 | 
				
			||||||
 | 
					usb_mtp_stall(int dev, const char *reason) "dev %d, reason: %s"
 | 
				
			||||||
 | 
					usb_mtp_op_get_device_info(int dev) "dev %d"
 | 
				
			||||||
 | 
					usb_mtp_op_open_session(int dev) "dev %d"
 | 
				
			||||||
 | 
					usb_mtp_op_close_session(int dev) "dev %d"
 | 
				
			||||||
 | 
					usb_mtp_op_get_storage_ids(int dev) "dev %d"
 | 
				
			||||||
 | 
					usb_mtp_op_get_storage_info(int dev) "dev %d"
 | 
				
			||||||
 | 
					usb_mtp_op_get_num_objects(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
 | 
				
			||||||
 | 
					usb_mtp_op_get_object_handles(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
 | 
				
			||||||
 | 
					usb_mtp_op_get_object_info(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
 | 
				
			||||||
 | 
					usb_mtp_op_get_object(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
 | 
				
			||||||
 | 
					usb_mtp_op_get_partial_object(int dev, uint32_t handle, const char *path, uint32_t offset, uint32_t length) "dev %d, handle 0x%x, path %s, off %d, len %d"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# hw/usb/host-libusb.c
 | 
					# hw/usb/host-libusb.c
 | 
				
			||||||
usb_host_open_started(int bus, int addr) "dev %d:%d"
 | 
					usb_host_open_started(int bus, int addr) "dev %d:%d"
 | 
				
			||||||
usb_host_open_success(int bus, int addr) "dev %d:%d"
 | 
					usb_host_open_success(int bus, int addr) "dev %d:%d"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								ui/sdl2.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								ui/sdl2.c
									
									
									
									
									
								
							@@ -278,7 +278,7 @@ static void sdl_hide_cursor(void)
 | 
				
			|||||||
        SDL_ShowCursor(1);
 | 
					        SDL_ShowCursor(1);
 | 
				
			||||||
        SDL_SetCursor(sdl_cursor_hidden);
 | 
					        SDL_SetCursor(sdl_cursor_hidden);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        SDL_ShowCursor(0);
 | 
					        SDL_SetRelativeMouseMode(SDL_TRUE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -289,6 +289,7 @@ static void sdl_show_cursor(void)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!qemu_input_is_absolute()) {
 | 
					    if (!qemu_input_is_absolute()) {
 | 
				
			||||||
 | 
					        SDL_SetRelativeMouseMode(SDL_FALSE);
 | 
				
			||||||
        SDL_ShowCursor(1);
 | 
					        SDL_ShowCursor(1);
 | 
				
			||||||
        if (guest_cursor &&
 | 
					        if (guest_cursor &&
 | 
				
			||||||
            (gui_grab || qemu_input_is_absolute() || absolute_enabled)) {
 | 
					            (gui_grab || qemu_input_is_absolute() || absolute_enabled)) {
 | 
				
			||||||
@@ -403,13 +404,17 @@ static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
 | 
					        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
 | 
				
			||||||
        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
 | 
					        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
 | 
				
			||||||
    } else if (guest_cursor) {
 | 
					    } else {
 | 
				
			||||||
        x -= guest_x;
 | 
					        if (guest_cursor) {
 | 
				
			||||||
        y -= guest_y;
 | 
					            x -= guest_x;
 | 
				
			||||||
        guest_x += x;
 | 
					            y -= guest_y;
 | 
				
			||||||
        guest_y += y;
 | 
					            guest_x += x;
 | 
				
			||||||
        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, x);
 | 
					            guest_y += y;
 | 
				
			||||||
        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, y);
 | 
					            dx = x;
 | 
				
			||||||
 | 
					            dy = y;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx);
 | 
				
			||||||
 | 
					        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    qemu_input_event_sync();
 | 
					    qemu_input_event_sync();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								user-exec.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								user-exec.c
									
									
									
									
									
								
							@@ -465,16 +465,29 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#elif defined(__aarch64__)
 | 
					#elif defined(__aarch64__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cpu_signal_handler(int host_signum, void *pinfo,
 | 
					int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
 | 
				
			||||||
                       void *puc)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    siginfo_t *info = pinfo;
 | 
					    siginfo_t *info = pinfo;
 | 
				
			||||||
    struct ucontext *uc = puc;
 | 
					    struct ucontext *uc = puc;
 | 
				
			||||||
    uint64_t pc;
 | 
					    uintptr_t pc = uc->uc_mcontext.pc;
 | 
				
			||||||
    int is_write = 0; /* XXX how to determine? */
 | 
					    uint32_t insn = *(uint32_t *)pc;
 | 
				
			||||||
 | 
					    bool is_write;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pc = uc->uc_mcontext.pc;
 | 
					    /* XXX: need kernel patch to get write flag faster.  */
 | 
				
			||||||
    return handle_cpu_signal(pc, (uint64_t)info->si_addr,
 | 
					    is_write = (   (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
 | 
				
			||||||
 | 
					                || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
 | 
				
			||||||
 | 
					                || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
 | 
				
			||||||
 | 
					                || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
 | 
				
			||||||
 | 
					                || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
 | 
				
			||||||
 | 
					                || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
 | 
				
			||||||
 | 
					                || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
 | 
				
			||||||
 | 
					                /* Ingore bits 10, 11 & 21, controlling indexing.  */
 | 
				
			||||||
 | 
					                || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
 | 
				
			||||||
 | 
					                || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
 | 
				
			||||||
 | 
					                /* Ignore bits 23 & 24, controlling indexing.  */
 | 
				
			||||||
 | 
					                || (insn & 0x3a400000) == 0x28000000); /* C3.3.7,14-16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return handle_cpu_signal(pc, (uintptr_t)info->si_addr,
 | 
				
			||||||
                             is_write, &uc->uc_sigmask, puc);
 | 
					                             is_write, &uc->uc_sigmask, puc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user