Compare commits
	
		
			74 Commits
		
	
	
		
			pull-input
			...
			pull-misc-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | dc9528fdf9 | ||
|  | 2396187076 | ||
|  | 01207d0b78 | ||
|  | 0ca540dbae | ||
|  | ed9b103d3e | ||
|  | c57ec3249e | ||
|  | fe6c53b4bb | ||
|  | b0f15a5d56 | ||
|  | 118760dfc9 | ||
|  | b304bf0021 | ||
|  | 3f1506704e | ||
|  | 0c126db27c | ||
|  | 72c1d3af6e | ||
|  | 2b194951c5 | ||
|  | c8f8f9fb2b | ||
|  | d2f41a1169 | ||
|  | 43a32ed68f | ||
|  | b29c8f115d | ||
|  | 0624976f61 | ||
|  | 7c2cb42b50 | ||
|  | af5199347a | ||
|  | c9dd4074df | ||
|  | 9b74d0d598 | ||
|  | 4b87dc4c97 | ||
|  | e9d818b8b1 | ||
|  | cbc14e6f28 | ||
|  | 16513b1b45 | ||
|  | e22492d332 | ||
|  | 919372251c | ||
|  | 863d7c9105 | ||
|  | 12b316d4c1 | ||
|  | 6cd859aa8a | ||
|  | b4c85ddcec | ||
|  | 38ee14f4f3 | ||
|  | e3c1adf16e | ||
|  | 2e7bcdb99a | ||
|  | 5264917bcf | ||
|  | 220c8ed536 | ||
|  | f1b7e0e498 | ||
|  | 175f099b30 | ||
|  | 15d914b18d | ||
|  | 262f6f5140 | ||
|  | 4a4fcdf6df | ||
|  | 4900116e6f | ||
|  | 8f480de0c9 | ||
|  | 5d12f961c6 | ||
|  | 6e1f0a55a1 | ||
|  | 8e46bbf362 | ||
|  | ddfa83ea06 | ||
|  | 6cb46e1e90 | ||
|  | 8dcf525abc | ||
|  | f8e2484389 | ||
|  | 523fdc08cc | ||
|  | 017a86f7ad | ||
|  | 2e796c7621 | ||
|  | 8d8db193f2 | ||
|  | a51a6b6ad5 | ||
|  | f029341494 | ||
|  | 7763ffa017 | ||
|  | 3353d0dcc3 | ||
|  | 82295d8a2d | ||
|  | 464400f6a5 | ||
|  | 4fed9421e9 | ||
|  | ac4df4e608 | ||
|  | fd8cec932c | ||
|  | b51910baf2 | ||
|  | 974a196d7f | ||
|  | f19e00d776 | ||
|  | 76ca310a19 | ||
| cd98d390ae | |||
|  | 8a3ae9109e | ||
|  | 4cf2348026 | ||
|  | f9a49dfa02 | ||
|  | 9ba3cf540f | 
| @@ -158,7 +158,6 @@ Guest CPU Cores (KVM): | ||||
| ---------------------- | ||||
|  | ||||
| Overall | ||||
| M: Gleb Natapov <gleb@redhat.com> | ||||
| M: Paolo Bonzini <pbonzini@redhat.com> | ||||
| L: kvm@vger.kernel.org | ||||
| S: Supported | ||||
| @@ -176,12 +175,14 @@ S: Maintained | ||||
| F: target-ppc/kvm.c | ||||
|  | ||||
| S390 | ||||
| M: Christian Borntraeger <borntraeger@de.ibm.com> | ||||
| M: Cornelia Huck <cornelia.huck@de.ibm.com> | ||||
| M: Alexander Graf <agraf@suse.de> | ||||
| S: Maintained | ||||
| F: target-s390x/kvm.c | ||||
| F: hw/intc/s390_flic.[hc] | ||||
|  | ||||
| X86 | ||||
| M: Gleb Natapov <gleb@redhat.com> | ||||
| M: Marcelo Tosatti <mtosatti@redhat.com> | ||||
| L: kvm@vger.kernel.org | ||||
| S: Supported | ||||
| @@ -495,10 +496,13 @@ F: hw/s390x/s390-*.c | ||||
|  | ||||
| S390 Virtio-ccw | ||||
| M: Cornelia Huck <cornelia.huck@de.ibm.com> | ||||
| M: Christian Borntraeger <borntraeger@de.ibm.com> | ||||
| M: Alexander Graf <agraf@suse.de> | ||||
| S: Supported | ||||
| F: hw/s390x/s390-virtio-ccw.c | ||||
| F: hw/s390x/css.[hc] | ||||
| F: hw/s390x/sclp*.[hc] | ||||
| F: hw/s390x/ipl*.[hc] | ||||
| T: git git://github.com/cohuck/qemu virtio-ccw-upstr | ||||
|  | ||||
| UniCore32 Machines | ||||
| @@ -629,6 +633,7 @@ F: hw/block/virtio-blk.c | ||||
|  | ||||
| virtio-ccw | ||||
| M: Cornelia Huck <cornelia.huck@de.ibm.com> | ||||
| M: Christian Borntraeger <borntraeger@de.ibm.com> | ||||
| S: Supported | ||||
| F: hw/s390x/virtio-ccw.[hc] | ||||
| T: git git://github.com/cohuck/qemu virtio-ccw-upstr | ||||
|   | ||||
							
								
								
									
										52
									
								
								arch_init.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								arch_init.c
									
									
									
									
									
								
							| @@ -164,8 +164,9 @@ static struct { | ||||
|     uint8_t *encoded_buf; | ||||
|     /* buffer for storing page content */ | ||||
|     uint8_t *current_buf; | ||||
|     /* Cache for XBZRLE */ | ||||
|     /* Cache for XBZRLE, Protected by lock. */ | ||||
|     PageCache *cache; | ||||
|     QemuMutex lock; | ||||
| } XBZRLE = { | ||||
|     .encoded_buf = NULL, | ||||
|     .current_buf = NULL, | ||||
| @@ -174,16 +175,52 @@ static struct { | ||||
| /* buffer used for XBZRLE decoding */ | ||||
| static uint8_t *xbzrle_decoded_buf; | ||||
|  | ||||
| static void XBZRLE_cache_lock(void) | ||||
| { | ||||
|     if (migrate_use_xbzrle()) | ||||
|         qemu_mutex_lock(&XBZRLE.lock); | ||||
| } | ||||
|  | ||||
| static void XBZRLE_cache_unlock(void) | ||||
| { | ||||
|     if (migrate_use_xbzrle()) | ||||
|         qemu_mutex_unlock(&XBZRLE.lock); | ||||
| } | ||||
|  | ||||
| int64_t xbzrle_cache_resize(int64_t new_size) | ||||
| { | ||||
|     PageCache *new_cache, *cache_to_free; | ||||
|  | ||||
|     if (new_size < TARGET_PAGE_SIZE) { | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     /* no need to lock, the current thread holds qemu big lock */ | ||||
|     if (XBZRLE.cache != NULL) { | ||||
|         return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) * | ||||
|             TARGET_PAGE_SIZE; | ||||
|         /* check XBZRLE.cache again later */ | ||||
|         if (pow2floor(new_size) == migrate_xbzrle_cache_size()) { | ||||
|             return pow2floor(new_size); | ||||
|         } | ||||
|         new_cache = cache_init(new_size / TARGET_PAGE_SIZE, | ||||
|                                         TARGET_PAGE_SIZE); | ||||
|         if (!new_cache) { | ||||
|             DPRINTF("Error creating cache\n"); | ||||
|             return -1; | ||||
|         } | ||||
|  | ||||
|         XBZRLE_cache_lock(); | ||||
|         /* the XBZRLE.cache may have be destroyed, check it again */ | ||||
|         if (XBZRLE.cache != NULL) { | ||||
|             cache_to_free = XBZRLE.cache; | ||||
|             XBZRLE.cache = new_cache; | ||||
|         } else { | ||||
|             cache_to_free = new_cache; | ||||
|         } | ||||
|         XBZRLE_cache_unlock(); | ||||
|  | ||||
|         cache_fini(cache_to_free); | ||||
|     } | ||||
|  | ||||
|     return pow2floor(new_size); | ||||
| } | ||||
|  | ||||
| @@ -539,6 +576,8 @@ static int ram_save_block(QEMUFile *f, bool last_stage) | ||||
|             ret = ram_control_save_page(f, block->offset, | ||||
|                                offset, TARGET_PAGE_SIZE, &bytes_sent); | ||||
|  | ||||
|             XBZRLE_cache_lock(); | ||||
|  | ||||
|             current_addr = block->offset + offset; | ||||
|             if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { | ||||
|                 if (ret != RAM_SAVE_CONTROL_DELAYED) { | ||||
| @@ -587,6 +626,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage) | ||||
|                 acct_info.norm_pages++; | ||||
|             } | ||||
|  | ||||
|             XBZRLE_cache_unlock(); | ||||
|             /* if page is unmodified, continue to the next */ | ||||
|             if (bytes_sent > 0) { | ||||
|                 last_sent_block = block; | ||||
| @@ -654,6 +694,7 @@ static void migration_end(void) | ||||
|         migration_bitmap = NULL; | ||||
|     } | ||||
|  | ||||
|     XBZRLE_cache_lock(); | ||||
|     if (XBZRLE.cache) { | ||||
|         cache_fini(XBZRLE.cache); | ||||
|         g_free(XBZRLE.cache); | ||||
| @@ -663,6 +704,7 @@ static void migration_end(void) | ||||
|         XBZRLE.encoded_buf = NULL; | ||||
|         XBZRLE.current_buf = NULL; | ||||
|     } | ||||
|     XBZRLE_cache_unlock(); | ||||
| } | ||||
|  | ||||
| static void ram_migration_cancel(void *opaque) | ||||
| @@ -693,13 +735,17 @@ static int ram_save_setup(QEMUFile *f, void *opaque) | ||||
|     dirty_rate_high_cnt = 0; | ||||
|  | ||||
|     if (migrate_use_xbzrle()) { | ||||
|         qemu_mutex_lock_iothread(); | ||||
|         XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() / | ||||
|                                   TARGET_PAGE_SIZE, | ||||
|                                   TARGET_PAGE_SIZE); | ||||
|         if (!XBZRLE.cache) { | ||||
|             qemu_mutex_unlock_iothread(); | ||||
|             DPRINTF("Error creating cache\n"); | ||||
|             return -1; | ||||
|         } | ||||
|         qemu_mutex_init(&XBZRLE.lock); | ||||
|         qemu_mutex_unlock_iothread(); | ||||
|  | ||||
|         /* We prefer not to abort if there is no memory */ | ||||
|         XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE); | ||||
|   | ||||
							
								
								
									
										10
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @@ -4107,7 +4107,11 @@ echo "vhost-net support $vhost_net" | ||||
| echo "vhost-scsi support $vhost_scsi" | ||||
| echo "Trace backend     $trace_backend" | ||||
| echo "Trace output file $trace_file-<pid>" | ||||
| if test "$spice" = "yes"; then | ||||
| echo "spice support     $spice ($spice_protocol_version/$spice_server_version)" | ||||
| else | ||||
| echo "spice support     $spice" | ||||
| fi | ||||
| echo "rbd support       $rbd" | ||||
| echo "xfsctl support    $xfs" | ||||
| echo "nss used          $smartcard_nss" | ||||
| @@ -4968,6 +4972,12 @@ for i in $ARCH $TARGET_BASE_ARCH ; do | ||||
|     echo "CONFIG_ALPHA_DIS=y"  >> $config_target_mak | ||||
|     echo "CONFIG_ALPHA_DIS=y"  >> config-all-disas.mak | ||||
|   ;; | ||||
|   aarch64) | ||||
|     if test -n "${cxx}"; then | ||||
|       echo "CONFIG_ARM_A64_DIS=y"  >> $config_target_mak | ||||
|       echo "CONFIG_ARM_A64_DIS=y"  >> config-all-disas.mak | ||||
|     fi | ||||
|   ;; | ||||
|   arm) | ||||
|     echo "CONFIG_ARM_DIS=y"  >> $config_target_mak | ||||
|     echo "CONFIG_ARM_DIS=y"  >> config-all-disas.mak | ||||
|   | ||||
							
								
								
									
										25
									
								
								cpus.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								cpus.c
									
									
									
									
									
								
							| @@ -1117,8 +1117,13 @@ void resume_all_vcpus(void) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* For temporary buffers for forming a name */ | ||||
| #define VCPU_THREAD_NAME_SIZE 16 | ||||
|  | ||||
| static void qemu_tcg_init_vcpu(CPUState *cpu) | ||||
| { | ||||
|     char thread_name[VCPU_THREAD_NAME_SIZE]; | ||||
|  | ||||
|     tcg_cpu_address_space_init(cpu, cpu->as); | ||||
|  | ||||
|     /* share a single thread for all cpus with TCG */ | ||||
| @@ -1127,8 +1132,10 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) | ||||
|         cpu->halt_cond = g_malloc0(sizeof(QemuCond)); | ||||
|         qemu_cond_init(cpu->halt_cond); | ||||
|         tcg_halt_cond = cpu->halt_cond; | ||||
|         qemu_thread_create(cpu->thread, qemu_tcg_cpu_thread_fn, cpu, | ||||
|                            QEMU_THREAD_JOINABLE); | ||||
|         snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", | ||||
|                  cpu->cpu_index); | ||||
|         qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, | ||||
|                            cpu, QEMU_THREAD_JOINABLE); | ||||
| #ifdef _WIN32 | ||||
|         cpu->hThread = qemu_thread_get_handle(cpu->thread); | ||||
| #endif | ||||
| @@ -1144,11 +1151,15 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) | ||||
|  | ||||
| static void qemu_kvm_start_vcpu(CPUState *cpu) | ||||
| { | ||||
|     char thread_name[VCPU_THREAD_NAME_SIZE]; | ||||
|  | ||||
|     cpu->thread = g_malloc0(sizeof(QemuThread)); | ||||
|     cpu->halt_cond = g_malloc0(sizeof(QemuCond)); | ||||
|     qemu_cond_init(cpu->halt_cond); | ||||
|     qemu_thread_create(cpu->thread, qemu_kvm_cpu_thread_fn, cpu, | ||||
|                        QEMU_THREAD_JOINABLE); | ||||
|     snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", | ||||
|              cpu->cpu_index); | ||||
|     qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, | ||||
|                        cpu, QEMU_THREAD_JOINABLE); | ||||
|     while (!cpu->created) { | ||||
|         qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); | ||||
|     } | ||||
| @@ -1156,10 +1167,14 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) | ||||
|  | ||||
| static void qemu_dummy_start_vcpu(CPUState *cpu) | ||||
| { | ||||
|     char thread_name[VCPU_THREAD_NAME_SIZE]; | ||||
|  | ||||
|     cpu->thread = g_malloc0(sizeof(QemuThread)); | ||||
|     cpu->halt_cond = g_malloc0(sizeof(QemuCond)); | ||||
|     qemu_cond_init(cpu->halt_cond); | ||||
|     qemu_thread_create(cpu->thread, qemu_dummy_cpu_thread_fn, cpu, | ||||
|     snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY", | ||||
|              cpu->cpu_index); | ||||
|     qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn, cpu, | ||||
|                        QEMU_THREAD_JOINABLE); | ||||
|     while (!cpu->created) { | ||||
|         qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); | ||||
|   | ||||
| @@ -1342,7 +1342,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, | ||||
|         ASSERT(format[5] == 'L'); | ||||
|         AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide()); | ||||
|         if (instr->ShiftMoveWide() > 0) { | ||||
|           AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide()); | ||||
|           AppendToOutput(", lsl #%" PRId64, 16 * instr->ShiftMoveWide()); | ||||
|         } | ||||
|       } | ||||
|       return 8; | ||||
| @@ -1391,7 +1391,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, | ||||
|     } | ||||
|     case 'F': {  // IFPSingle, IFPDouble or IFPFBits. | ||||
|       if (format[3] == 'F') {  // IFPFbits. | ||||
|         AppendToOutput("#%d", 64 - instr->FPScale()); | ||||
|         AppendToOutput("#%" PRId64, 64 - instr->FPScale()); | ||||
|         return 8; | ||||
|       } else { | ||||
|         AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(), | ||||
| @@ -1412,23 +1412,23 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, | ||||
|       return 5; | ||||
|     } | ||||
|     case 'P': {  // IP - Conditional compare. | ||||
|       AppendToOutput("#%d", instr->ImmCondCmp()); | ||||
|       AppendToOutput("#%" PRId64, instr->ImmCondCmp()); | ||||
|       return 2; | ||||
|     } | ||||
|     case 'B': {  // Bitfields. | ||||
|       return SubstituteBitfieldImmediateField(instr, format); | ||||
|     } | ||||
|     case 'E': {  // IExtract. | ||||
|       AppendToOutput("#%d", instr->ImmS()); | ||||
|       AppendToOutput("#%" PRId64, instr->ImmS()); | ||||
|       return 8; | ||||
|     } | ||||
|     case 'S': {  // IS - Test and branch bit. | ||||
|       AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) | | ||||
|                             instr->ImmTestBranchBit40()); | ||||
|       AppendToOutput("#%" PRId64, (instr->ImmTestBranchBit5() << 5) | | ||||
|                                   instr->ImmTestBranchBit40()); | ||||
|       return 2; | ||||
|     } | ||||
|     case 'D': {  // IDebug - HLT and BRK instructions. | ||||
|       AppendToOutput("#0x%x", instr->ImmException()); | ||||
|       AppendToOutput("#0x%" PRIx64, instr->ImmException()); | ||||
|       return 6; | ||||
|     } | ||||
|     default: { | ||||
| @@ -1598,12 +1598,12 @@ int Disassembler::SubstituteExtendField(Instruction* instr, | ||||
|       (((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) || | ||||
|        (instr->ExtendMode() == UXTX))) { | ||||
|     if (instr->ImmExtendShift() > 0) { | ||||
|       AppendToOutput(", lsl #%d", instr->ImmExtendShift()); | ||||
|       AppendToOutput(", lsl #%" PRId64, instr->ImmExtendShift()); | ||||
|     } | ||||
|   } else { | ||||
|     AppendToOutput(", %s", extend_mode[instr->ExtendMode()]); | ||||
|     if (instr->ImmExtendShift() > 0) { | ||||
|       AppendToOutput(" #%d", instr->ImmExtendShift()); | ||||
|       AppendToOutput(" #%" PRId64, instr->ImmExtendShift()); | ||||
|     } | ||||
|   } | ||||
|   return 3; | ||||
| @@ -1632,7 +1632,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr, | ||||
|   if (!((ext == UXTX) && (shift == 0))) { | ||||
|     AppendToOutput(", %s", extend_mode[ext]); | ||||
|     if (shift != 0) { | ||||
|       AppendToOutput(" #%d", instr->SizeLS()); | ||||
|       AppendToOutput(" #%" PRId64, instr->SizeLS()); | ||||
|     } | ||||
|   } | ||||
|   return 9; | ||||
|   | ||||
| @@ -11,99 +11,92 @@ | ||||
| ; (Com+Lpt)" from the list.  Click "Have a disk".  Select this file. | ||||
| ; Procedure may vary a bit depending on the windows version. | ||||
|  | ||||
| ; FIXME: This file covers the single port version only. | ||||
| ; This file covers all options: pci-serial, pci-serial-2x, pci-serial-4x | ||||
| ; for both 32 and 64 bit platforms. | ||||
|  | ||||
| [Version] | ||||
| Signature="$CHICAGO$" | ||||
| Class=Ports | ||||
| ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} | ||||
| Signature="$Windows NT$" | ||||
| Class=MultiFunction | ||||
| ClassGUID={4d36e971-e325-11ce-bfc1-08002be10318} | ||||
| Provider=%QEMU% | ||||
| DriverVer=09/24/2012,1.3.0 | ||||
|  | ||||
| [SourceDisksNames] | ||||
| 3426=windows cd | ||||
|  | ||||
| [SourceDisksFiles] | ||||
| serial.sys 		= 3426 | ||||
| serenum.sys 		= 3426 | ||||
|  | ||||
| [DestinationDirs] | ||||
| DefaultDestDir  = 11        ;LDID_SYS | ||||
| ComPort.NT.Copy = 12        ;DIRID_DRIVERS | ||||
| SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS | ||||
|  | ||||
| ; Drivers | ||||
| ;---------------------------------------------------------- | ||||
| DriverVer=12/29/2013,1.3.0 | ||||
| [ControlFlags] | ||||
| ExcludeFromSelect=* | ||||
| [Manufacturer] | ||||
| %QEMU%=QEMU,NTx86 | ||||
| %QEMU%=QEMU,NTx86,NTAMD64 | ||||
|  | ||||
| [QEMU.NTx86] | ||||
| %QEMU-PCI_SERIAL.DeviceDesc% = ComPort, "PCI\VEN_1b36&DEV_0002&CC_0700" | ||||
| %QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36&DEV_0002 | ||||
| %QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36&DEV_0003 | ||||
| %QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36&DEV_0004 | ||||
|  | ||||
| ; COM sections | ||||
| ;---------------------------------------------------------- | ||||
| [ComPort.AddReg] | ||||
| HKR,,PortSubClass,1,01 | ||||
| [QEMU.NTAMD64] | ||||
| %QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36&DEV_0002 | ||||
| %QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36&DEV_0003 | ||||
| %QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36&DEV_0004 | ||||
|  | ||||
| [ComPort.NT] | ||||
| AddReg=ComPort.AddReg, ComPort.NT.AddReg | ||||
| LogConfig=caa | ||||
| SyssetupPnPFlags = 1 | ||||
| [ComPort_inst1] | ||||
| Include=mf.inf | ||||
| Needs=MFINSTALL.mf | ||||
|  | ||||
| [ComPort.NT.HW] | ||||
| AddReg=ComPort.NT.HW.AddReg | ||||
| [ComPort_inst2] | ||||
| Include=mf.inf | ||||
| Needs=MFINSTALL.mf | ||||
|  | ||||
| [ComPort.NT.AddReg] | ||||
| HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" | ||||
| [ComPort_inst4] | ||||
| Include=mf.inf | ||||
| Needs=MFINSTALL.mf | ||||
|  | ||||
| [ComPort.NT.HW.AddReg] | ||||
| HKR,,"UpperFilters",0x00010000,"serenum" | ||||
| [ComPort_inst1.HW] | ||||
| AddReg=ComPort_inst1.RegHW | ||||
|  | ||||
| ;-------------- Service installation | ||||
| ; Port Driver (function driver for this device) | ||||
| [ComPort.NT.Services] | ||||
| AddService = Serial, 0x00000002, Serial_Service_Inst, Serial_EventLog_Inst | ||||
| AddService = Serenum,,Serenum_Service_Inst | ||||
| [ComPort_inst2.HW] | ||||
| AddReg=ComPort_inst2.RegHW | ||||
|  | ||||
| ; -------------- Serial Port Driver install sections | ||||
| [Serial_Service_Inst] | ||||
| DisplayName    = %Serial.SVCDESC% | ||||
| ServiceType    = 1               ; SERVICE_KERNEL_DRIVER | ||||
| StartType      = 1               ; SERVICE_SYSTEM_START (this driver may do detection) | ||||
| ErrorControl   = 0               ; SERVICE_ERROR_IGNORE | ||||
| ServiceBinary  = %12%\serial.sys | ||||
| LoadOrderGroup = Extended base | ||||
| [ComPort_inst4.HW] | ||||
| AddReg=ComPort_inst4.RegHW | ||||
|  | ||||
| ; -------------- Serenum Driver install section | ||||
| [Serenum_Service_Inst] | ||||
| DisplayName    = %Serenum.SVCDESC% | ||||
| ServiceType    = 1               ; SERVICE_KERNEL_DRIVER | ||||
| StartType      = 3               ; SERVICE_DEMAND_START | ||||
| ErrorControl   = 1               ; SERVICE_ERROR_NORMAL | ||||
| ServiceBinary  = %12%\serenum.sys | ||||
| LoadOrderGroup = PNP Filter | ||||
| [ComPort_inst1.Services] | ||||
| Include=mf.inf | ||||
| Needs=MFINSTALL.mf.Services | ||||
|  | ||||
| [Serial_EventLog_Inst] | ||||
| AddReg = Serial_EventLog_AddReg | ||||
| [ComPort_inst2.Services] | ||||
| Include=mf.inf | ||||
| Needs=MFINSTALL.mf.Services | ||||
|  | ||||
| [Serial_EventLog_AddReg] | ||||
| HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys" | ||||
| HKR,,TypesSupported,0x00010001,7 | ||||
| [ComPort_inst4.Services] | ||||
| Include=mf.inf | ||||
| Needs=MFINSTALL.mf.Services | ||||
|  | ||||
| ; The following sections are COM port resource configs. | ||||
| ; Section name format means: | ||||
| ; Char 1 = c (COM port) | ||||
| ; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any) | ||||
| ; Char 3 = IRQ config: #, a (any) | ||||
| [ComPort_inst1.RegHW] | ||||
| HKR,Child0000,HardwareID,,*PNP0501 | ||||
| HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00 | ||||
| HKR,Child0000,ResourceMap,1,02 | ||||
|  | ||||
| [caa]                   ; Any base, any IRQ | ||||
| ConfigPriority=HARDRECONFIG | ||||
| IOConfig=8@100-ffff%fff8(3ff::) | ||||
| IRQConfig=S:3,4,5,7,9,10,11,12,14,15 | ||||
| [ComPort_inst2.RegHW] | ||||
| HKR,Child0000,HardwareID,,*PNP0501 | ||||
| HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00 | ||||
| HKR,Child0000,ResourceMap,1,02 | ||||
| HKR,Child0001,HardwareID,,*PNP0501 | ||||
| HKR,Child0001,VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00 | ||||
| HKR,Child0001,ResourceMap,1,02 | ||||
|  | ||||
| [ComPort_inst4.RegHW] | ||||
| HKR,Child0000,HardwareID,,*PNP0501 | ||||
| HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00 | ||||
| HKR,Child0000,ResourceMap,1,02 | ||||
| HKR,Child0001,HardwareID,,*PNP0501 | ||||
| HKR,Child0001,VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00 | ||||
| HKR,Child0001,ResourceMap,1,02 | ||||
| HKR,Child0002,HardwareID,,*PNP0501 | ||||
| HKR,Child0002,VaryingResourceMap,1,00, 10,00,00,00, 08,00,00,00 | ||||
| HKR,Child0002,ResourceMap,1,02 | ||||
| HKR,Child0003,HardwareID,,*PNP0501 | ||||
| HKR,Child0003,VaryingResourceMap,1,00, 18,00,00,00, 08,00,00,00 | ||||
| HKR,Child0003,ResourceMap,1,02 | ||||
|  | ||||
| [Strings] | ||||
| QEMU="QEMU" | ||||
| QEMU-PCI_SERIAL.DeviceDesc="QEMU Serial PCI Card" | ||||
|  | ||||
| Serial.SVCDESC   = "Serial port driver" | ||||
| Serenum.SVCDESC = "Serenum Filter Driver" | ||||
| QEMU-PCI_SERIAL_1_PORT="1x QEMU PCI Serial Card" | ||||
| QEMU-PCI_SERIAL_2_PORT="2x QEMU PCI Serial Card" | ||||
| QEMU-PCI_SERIAL_4_PORT="4x QEMU PCI Serial Card" | ||||
|   | ||||
							
								
								
									
										14
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								exec.c
									
									
									
									
									
								
							| @@ -1029,7 +1029,7 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|  | ||||
|     hpagesize = gethugepagesize(path); | ||||
|     if (!hpagesize) { | ||||
|         return NULL; | ||||
|         goto error; | ||||
|     } | ||||
|  | ||||
|     if (memory < hpagesize) { | ||||
| @@ -1038,7 +1038,7 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|  | ||||
|     if (kvm_enabled() && !kvm_has_sync_mmu()) { | ||||
|         fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n"); | ||||
|         return NULL; | ||||
|         goto error; | ||||
|     } | ||||
|  | ||||
|     /* Make name safe to use with mkstemp by replacing '/' with '_'. */ | ||||
| @@ -1056,7 +1056,7 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|     if (fd < 0) { | ||||
|         perror("unable to create backing store for hugepages"); | ||||
|         g_free(filename); | ||||
|         return NULL; | ||||
|         goto error; | ||||
|     } | ||||
|     unlink(filename); | ||||
|     g_free(filename); | ||||
| @@ -1076,7 +1076,7 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|     if (area == MAP_FAILED) { | ||||
|         perror("file_ram_alloc: can't mmap RAM pages"); | ||||
|         close(fd); | ||||
|         return (NULL); | ||||
|         goto error; | ||||
|     } | ||||
|  | ||||
|     if (mem_prealloc) { | ||||
| @@ -1120,6 +1120,12 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|  | ||||
|     block->fd = fd; | ||||
|     return area; | ||||
|  | ||||
| error: | ||||
|     if (mem_prealloc) { | ||||
|         exit(1); | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| #else | ||||
| static void *file_ram_alloc(RAMBlock *block, | ||||
|   | ||||
| @@ -110,10 +110,10 @@ | ||||
| #define MP_PHY_88E3015          0x01410E20 | ||||
|  | ||||
| /* TX descriptor status */ | ||||
| #define MP_ETH_TX_OWN           (1 << 31) | ||||
| #define MP_ETH_TX_OWN           (1U << 31) | ||||
|  | ||||
| /* RX descriptor status */ | ||||
| #define MP_ETH_RX_OWN           (1 << 31) | ||||
| #define MP_ETH_RX_OWN           (1U << 31) | ||||
|  | ||||
| /* Interrupt cause/mask bits */ | ||||
| #define MP_ETH_IRQ_RX_BIT       0 | ||||
|   | ||||
| @@ -809,22 +809,26 @@ static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s, | ||||
|                 uint32_t diff, uint32_t value) | ||||
| { | ||||
|     if (s->compat1509) { | ||||
|         if (diff & (1 << 31))			/* MCBSP3_CLK_HIZ_DI */ | ||||
|             omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), | ||||
|                             (value >> 31) & 1); | ||||
|         if (diff & (1 << 1))			/* CLK32K */ | ||||
|             omap_clk_onoff(omap_findclk(s, "clk32k_out"), | ||||
|                             (~value >> 1) & 1); | ||||
|         if (diff & (1U << 31)) { | ||||
|             /* MCBSP3_CLK_HIZ_DI */ | ||||
|             omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), (value >> 31) & 1); | ||||
|         } | ||||
|         if (diff & (1 << 1)) { | ||||
|             /* CLK32K */ | ||||
|             omap_clk_onoff(omap_findclk(s, "clk32k_out"), (~value >> 1) & 1); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s, | ||||
|                 uint32_t diff, uint32_t value) | ||||
| { | ||||
|     if (diff & (1 << 31))			/* CONF_MOD_UART3_CLK_MODE_R */ | ||||
|          omap_clk_reparent(omap_findclk(s, "uart3_ck"), | ||||
|                          omap_findclk(s, ((value >> 31) & 1) ? | ||||
|                                  "ck_48m" : "armper_ck")); | ||||
|     if (diff & (1U << 31)) { | ||||
|         /* CONF_MOD_UART3_CLK_MODE_R */ | ||||
|         omap_clk_reparent(omap_findclk(s, "uart3_ck"), | ||||
|                           omap_findclk(s, ((value >> 31) & 1) ? | ||||
|                                        "ck_48m" : "armper_ck")); | ||||
|     } | ||||
|     if (diff & (1 << 30))			/* CONF_MOD_UART2_CLK_MODE_R */ | ||||
|          omap_clk_reparent(omap_findclk(s, "uart2_ck"), | ||||
|                          omap_findclk(s, ((value >> 30) & 1) ? | ||||
|   | ||||
| @@ -259,7 +259,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||||
|  | ||||
|     case 1: | ||||
|         /* Idle */ | ||||
|         if (!(s->cm_regs[CCCR >> 2] & (1 << 31))) { /* CPDIS */ | ||||
|         if (!(s->cm_regs[CCCR >> 2] & (1U << 31))) { /* CPDIS */ | ||||
|             cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT); | ||||
|             break; | ||||
|         } | ||||
| @@ -496,7 +496,7 @@ typedef struct { | ||||
| #define SSCR0_SSE	(1 << 7) | ||||
| #define SSCR0_RIM	(1 << 22) | ||||
| #define SSCR0_TIM	(1 << 23) | ||||
| #define SSCR0_MOD	(1 << 31) | ||||
| #define SSCR0_MOD       (1U << 31) | ||||
| #define SSCR0_DSS(x)	(((((x) >> 16) & 0x10) | ((x) & 0xf)) + 1) | ||||
| #define SSCR1_RIE	(1 << 0) | ||||
| #define SSCR1_TIE	(1 << 1) | ||||
| @@ -1006,7 +1006,7 @@ static void pxa2xx_rtc_write(void *opaque, hwaddr addr, | ||||
|  | ||||
|     switch (addr) { | ||||
|     case RTTR: | ||||
|         if (!(s->rttr & (1 << 31))) { | ||||
|         if (!(s->rttr & (1U << 31))) { | ||||
|             pxa2xx_rtc_hzupdate(s); | ||||
|             s->rttr = value; | ||||
|             pxa2xx_rtc_alarm_update(s, s->rtsr); | ||||
|   | ||||
| @@ -110,7 +110,7 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level) | ||||
|     } | ||||
|  | ||||
|     bank = line >> 5; | ||||
|     mask = 1 << (line & 31); | ||||
|     mask = 1U << (line & 31); | ||||
|  | ||||
|     if (level) { | ||||
|         s->status[bank] |= s->rising[bank] & mask & | ||||
|   | ||||
| @@ -105,7 +105,7 @@ static inline uint32_t pxa2xx_pic_highest(PXA2xxPICState *s) { | ||||
|  | ||||
|     for (i = PXA2XX_PIC_SRCS - 1; i >= 0; i --) { | ||||
|         irq = s->priority[i] & 0x3f; | ||||
|         if ((s->priority[i] & (1 << 31)) && irq < PXA2XX_PIC_SRCS) { | ||||
|         if ((s->priority[i] & (1U << 31)) && irq < PXA2XX_PIC_SRCS) { | ||||
|             /* Source peripheral ID is valid.  */ | ||||
|             bit = 1 << (irq & 31); | ||||
|             int_set = (irq >= 32); | ||||
| @@ -119,7 +119,7 @@ static inline uint32_t pxa2xx_pic_highest(PXA2xxPICState *s) { | ||||
|             if (mask[int_set] & bit & ~s->is_fiq[int_set]) { | ||||
|                 /* IRQ asserted */ | ||||
|                 ichp &= 0x0000ffff; | ||||
|                 ichp |= (1 << 31) | (irq << 16); | ||||
|                 ichp |= (1U << 31) | (irq << 16); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -358,7 +358,7 @@ static void start_data_plane_bh(void *opaque) | ||||
|  | ||||
|     qemu_bh_delete(s->start_bh); | ||||
|     s->start_bh = NULL; | ||||
|     qemu_thread_create(&s->thread, data_plane_thread, | ||||
|     qemu_thread_create(&s->thread, "data_plane", data_plane_thread, | ||||
|                        s, QEMU_THREAD_JOINABLE); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -643,6 +643,21 @@ static inline char acpi_get_hex(uint32_t val) | ||||
| #define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start) | ||||
| #define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start) | ||||
|  | ||||
| #define ACPI_PCINOHP_OFFSET_HEX (*ssdt_pcinohp_name - *ssdt_pcinohp_start + 1) | ||||
| #define ACPI_PCINOHP_OFFSET_ADR (*ssdt_pcinohp_adr - *ssdt_pcinohp_start) | ||||
| #define ACPI_PCINOHP_SIZEOF (*ssdt_pcinohp_end - *ssdt_pcinohp_start) | ||||
| #define ACPI_PCINOHP_AML (ssdp_pcihp_aml + *ssdt_pcinohp_start) | ||||
|  | ||||
| #define ACPI_PCIVGA_OFFSET_HEX (*ssdt_pcivga_name - *ssdt_pcivga_start + 1) | ||||
| #define ACPI_PCIVGA_OFFSET_ADR (*ssdt_pcivga_adr - *ssdt_pcivga_start) | ||||
| #define ACPI_PCIVGA_SIZEOF (*ssdt_pcivga_end - *ssdt_pcivga_start) | ||||
| #define ACPI_PCIVGA_AML (ssdp_pcihp_aml + *ssdt_pcivga_start) | ||||
|  | ||||
| #define ACPI_PCIQXL_OFFSET_HEX (*ssdt_pciqxl_name - *ssdt_pciqxl_start + 1) | ||||
| #define ACPI_PCIQXL_OFFSET_ADR (*ssdt_pciqxl_adr - *ssdt_pciqxl_start) | ||||
| #define ACPI_PCIQXL_SIZEOF (*ssdt_pciqxl_end - *ssdt_pciqxl_start) | ||||
| #define ACPI_PCIQXL_AML (ssdp_pcihp_aml + *ssdt_pciqxl_start) | ||||
|  | ||||
| #define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */ | ||||
| #define ACPI_SSDT_HEADER_LENGTH 36 | ||||
|  | ||||
| @@ -677,6 +692,33 @@ static void patch_pcihp(int slot, uint8_t *ssdt_ptr) | ||||
|     ssdt_ptr[ACPI_PCIHP_OFFSET_ADR + 2] = slot; | ||||
| } | ||||
|  | ||||
| static void patch_pcinohp(int slot, uint8_t *ssdt_ptr) | ||||
| { | ||||
|     unsigned devfn = PCI_DEVFN(slot, 0); | ||||
|  | ||||
|     ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4); | ||||
|     ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX + 1] = acpi_get_hex(devfn); | ||||
|     ssdt_ptr[ACPI_PCINOHP_OFFSET_ADR + 2] = slot; | ||||
| } | ||||
|  | ||||
| static void patch_pcivga(int slot, uint8_t *ssdt_ptr) | ||||
| { | ||||
|     unsigned devfn = PCI_DEVFN(slot, 0); | ||||
|  | ||||
|     ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX] = acpi_get_hex(devfn >> 4); | ||||
|     ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX + 1] = acpi_get_hex(devfn); | ||||
|     ssdt_ptr[ACPI_PCIVGA_OFFSET_ADR + 2] = slot; | ||||
| } | ||||
|  | ||||
| static void patch_pciqxl(int slot, uint8_t *ssdt_ptr) | ||||
| { | ||||
|     unsigned devfn = PCI_DEVFN(slot, 0); | ||||
|  | ||||
|     ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX] = acpi_get_hex(devfn >> 4); | ||||
|     ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX + 1] = acpi_get_hex(devfn); | ||||
|     ssdt_ptr[ACPI_PCIQXL_OFFSET_ADR + 2] = slot; | ||||
| } | ||||
|  | ||||
| /* Assign BSEL property to all buses.  In the future, this can be changed | ||||
|  * to only assign to buses that support hotplug. | ||||
|  */ | ||||
| @@ -737,6 +779,10 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) | ||||
|     AcpiBuildPciBusHotplugState *parent = child->parent; | ||||
|     GArray *bus_table = build_alloc_array(); | ||||
|     DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX); | ||||
|     DECLARE_BITMAP(slot_device_present, PCI_SLOT_MAX); | ||||
|     DECLARE_BITMAP(slot_device_system, PCI_SLOT_MAX); | ||||
|     DECLARE_BITMAP(slot_device_vga, PCI_SLOT_MAX); | ||||
|     DECLARE_BITMAP(slot_device_qxl, PCI_SLOT_MAX); | ||||
|     uint8_t op; | ||||
|     int i; | ||||
|     QObject *bsel; | ||||
| @@ -764,40 +810,82 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) | ||||
|         build_append_byte(bus_table, 0x08); /* NameOp */ | ||||
|         build_append_nameseg(bus_table, "BSEL"); | ||||
|         build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel))); | ||||
|  | ||||
|         memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable); | ||||
|     } else { | ||||
|         /* No bsel - no slots are hot-pluggable */ | ||||
|         memset(slot_hotplug_enable, 0x00, sizeof slot_hotplug_enable); | ||||
|     } | ||||
|  | ||||
|         for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { | ||||
|             DeviceClass *dc; | ||||
|             PCIDeviceClass *pc; | ||||
|             PCIDevice *pdev = bus->devices[i]; | ||||
|     memset(slot_device_present, 0x00, sizeof slot_device_present); | ||||
|     memset(slot_device_system, 0x00, sizeof slot_device_present); | ||||
|     memset(slot_device_vga, 0x00, sizeof slot_device_vga); | ||||
|     memset(slot_device_qxl, 0x00, sizeof slot_device_qxl); | ||||
|  | ||||
|             if (!pdev) { | ||||
|                 continue; | ||||
|             } | ||||
|     for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) { | ||||
|         DeviceClass *dc; | ||||
|         PCIDeviceClass *pc; | ||||
|         PCIDevice *pdev = bus->devices[i]; | ||||
|         int slot = PCI_SLOT(i); | ||||
|  | ||||
|             pc = PCI_DEVICE_GET_CLASS(pdev); | ||||
|             dc = DEVICE_GET_CLASS(pdev); | ||||
|         if (!pdev) { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|             if (!dc->hotpluggable || pc->is_bridge) { | ||||
|                 int slot = PCI_SLOT(i); | ||||
|         set_bit(slot, slot_device_present); | ||||
|         pc = PCI_DEVICE_GET_CLASS(pdev); | ||||
|         dc = DEVICE_GET_CLASS(pdev); | ||||
|  | ||||
|                 clear_bit(slot, slot_hotplug_enable); | ||||
|         if (pc->class_id == PCI_CLASS_BRIDGE_ISA) { | ||||
|             set_bit(slot, slot_device_system); | ||||
|         } | ||||
|  | ||||
|         if (pc->class_id == PCI_CLASS_DISPLAY_VGA) { | ||||
|             set_bit(slot, slot_device_vga); | ||||
|  | ||||
|             if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) { | ||||
|                 set_bit(slot, slot_device_qxl); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* Append Device object for each slot which supports eject */ | ||||
|         for (i = 0; i < PCI_SLOT_MAX; i++) { | ||||
|             bool can_eject = test_bit(i, slot_hotplug_enable); | ||||
|             if (can_eject) { | ||||
|                 void *pcihp = acpi_data_push(bus_table, | ||||
|                                              ACPI_PCIHP_SIZEOF); | ||||
|                 memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); | ||||
|                 patch_pcihp(i, pcihp); | ||||
|                 bus_hotplug_support = true; | ||||
|             } | ||||
|         if (!dc->hotpluggable || pc->is_bridge) { | ||||
|             clear_bit(slot, slot_hotplug_enable); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* Append Device object for each slot */ | ||||
|     for (i = 0; i < PCI_SLOT_MAX; i++) { | ||||
|         bool can_eject = test_bit(i, slot_hotplug_enable); | ||||
|         bool present = test_bit(i, slot_device_present); | ||||
|         bool vga = test_bit(i, slot_device_vga); | ||||
|         bool qxl = test_bit(i, slot_device_qxl); | ||||
|         bool system = test_bit(i, slot_device_system); | ||||
|         if (can_eject) { | ||||
|             void *pcihp = acpi_data_push(bus_table, | ||||
|                                          ACPI_PCIHP_SIZEOF); | ||||
|             memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); | ||||
|             patch_pcihp(i, pcihp); | ||||
|             bus_hotplug_support = true; | ||||
|         } else if (qxl) { | ||||
|             void *pcihp = acpi_data_push(bus_table, | ||||
|                                          ACPI_PCIQXL_SIZEOF); | ||||
|             memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF); | ||||
|             patch_pciqxl(i, pcihp); | ||||
|         } else if (vga) { | ||||
|             void *pcihp = acpi_data_push(bus_table, | ||||
|                                          ACPI_PCIVGA_SIZEOF); | ||||
|             memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF); | ||||
|             patch_pcivga(i, pcihp); | ||||
|         } else if (system) { | ||||
|             /* Nothing to do: system devices are in DSDT. */ | ||||
|         } else if (present) { | ||||
|             void *pcihp = acpi_data_push(bus_table, | ||||
|                                          ACPI_PCINOHP_SIZEOF); | ||||
|             memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); | ||||
|             patch_pcinohp(i, pcihp); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (bsel) { | ||||
|         method = build_alloc_method("DVNT", 2); | ||||
|  | ||||
|         for (i = 0; i < PCI_SLOT_MAX; i++) { | ||||
| @@ -976,7 +1064,14 @@ build_ssdt(GArray *table_data, GArray *linker, | ||||
|  | ||||
|         { | ||||
|             AcpiBuildPciBusHotplugState hotplug_state; | ||||
|             PCIBus *bus = find_i440fx(); /* TODO: Q35 support */ | ||||
|             Object *pci_host; | ||||
|             PCIBus *bus = NULL; | ||||
|             bool ambiguous; | ||||
|  | ||||
|             pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous); | ||||
|             if (!ambiguous && pci_host) { | ||||
|                 bus = PCI_HOST_BRIDGE(pci_host)->bus; | ||||
|             } | ||||
|  | ||||
|             build_pci_bus_state_init(&hotplug_state, NULL); | ||||
|  | ||||
|   | ||||
| @@ -80,6 +80,8 @@ DefinitionBlock ( | ||||
|             Name(_HID, EisaId("PNP0A03")) | ||||
|             Name(_ADR, 0x00) | ||||
|             Name(_UID, 1) | ||||
| //#define PX13 S0B_ | ||||
| //            External(PX13, DeviceObj) | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -87,34 +89,6 @@ DefinitionBlock ( | ||||
| #include "acpi-dsdt-hpet.dsl" | ||||
|  | ||||
|  | ||||
| /**************************************************************** | ||||
|  * VGA | ||||
|  ****************************************************************/ | ||||
|  | ||||
|     Scope(\_SB.PCI0) { | ||||
|         Device(VGA) { | ||||
|             Name(_ADR, 0x00020000) | ||||
|             OperationRegion(PCIC, PCI_Config, Zero, 0x4) | ||||
|             Field(PCIC, DWordAcc, NoLock, Preserve) { | ||||
|                 VEND, 32 | ||||
|             } | ||||
|             Method(_S1D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S2D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S3D, 0, NotSerialized) { | ||||
|                 If (LEqual(VEND, 0x1001b36)) { | ||||
|                     Return (0x03)           // QXL | ||||
|                 } Else { | ||||
|                     Return (0x00) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| /**************************************************************** | ||||
|  * PIIX4 PM | ||||
|  ****************************************************************/ | ||||
| @@ -132,6 +106,9 @@ DefinitionBlock ( | ||||
|  ****************************************************************/ | ||||
|  | ||||
|     Scope(\_SB.PCI0) { | ||||
|  | ||||
|         External(ISA, DeviceObj) | ||||
|  | ||||
|         Device(ISA) { | ||||
|             Name(_ADR, 0x00010000) | ||||
|  | ||||
|   | ||||
| @@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x53, | ||||
| 0x44, | ||||
| 0x54, | ||||
| 0x87, | ||||
| 0x85, | ||||
| 0x11, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xb8, | ||||
| 0x8b, | ||||
| 0x42, | ||||
| 0x58, | ||||
| 0x50, | ||||
| @@ -146,7 +146,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x1, | ||||
| 0x10, | ||||
| 0x4e, | ||||
| 0x15, | ||||
| 0x18, | ||||
| 0x2e, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| @@ -163,9 +163,9 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x53, | ||||
| 0x11, | ||||
| 0x42, | ||||
| 0x7, | ||||
| 0xa, | ||||
| 0x6e, | ||||
| 0xa, | ||||
| 0x9e, | ||||
| 0x88, | ||||
| 0xd, | ||||
| 0x0, | ||||
| @@ -217,11 +217,59 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x0, | ||||
| 0xd, | ||||
| 0xff, | ||||
| 0xad, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xa1, | ||||
| 0x88, | ||||
| 0xd, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xc, | ||||
| 0x3, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xf, | ||||
| 0xae, | ||||
| 0xff, | ||||
| 0xae, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xf1, | ||||
| 0x0, | ||||
| 0x88, | ||||
| 0xd, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xc, | ||||
| 0x3, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x20, | ||||
| 0xaf, | ||||
| 0xdf, | ||||
| 0xaf, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xc0, | ||||
| 0x0, | ||||
| 0x88, | ||||
| 0xd, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xc, | ||||
| 0x3, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xe4, | ||||
| 0xaf, | ||||
| 0xff, | ||||
| 0xff, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xf3, | ||||
| 0x1c, | ||||
| 0x50, | ||||
| 0x87, | ||||
| 0x17, | ||||
| 0x0, | ||||
| @@ -347,7 +395,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x45, | ||||
| 0x53, | ||||
| 0xa, | ||||
| 0x5c, | ||||
| 0x8c, | ||||
| 0x50, | ||||
| 0x53, | ||||
| 0x33, | ||||
| @@ -358,7 +406,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x45, | ||||
| 0x53, | ||||
| 0xa, | ||||
| 0x60, | ||||
| 0x90, | ||||
| 0x50, | ||||
| 0x45, | ||||
| 0x33, | ||||
| @@ -369,7 +417,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x45, | ||||
| 0x53, | ||||
| 0xa, | ||||
| 0x68, | ||||
| 0x98, | ||||
| 0x50, | ||||
| 0x4c, | ||||
| 0x33, | ||||
| @@ -638,103 +686,6 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x79, | ||||
| 0x0, | ||||
| 0x10, | ||||
| 0x40, | ||||
| 0x6, | ||||
| 0x2e, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x42, | ||||
| 0x5f, | ||||
| 0x50, | ||||
| 0x43, | ||||
| 0x49, | ||||
| 0x30, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x43, | ||||
| 0x5, | ||||
| 0x56, | ||||
| 0x47, | ||||
| 0x41, | ||||
| 0x5f, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x41, | ||||
| 0x44, | ||||
| 0x52, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x2, | ||||
| 0x0, | ||||
| 0x5b, | ||||
| 0x80, | ||||
| 0x50, | ||||
| 0x43, | ||||
| 0x49, | ||||
| 0x43, | ||||
| 0x2, | ||||
| 0x0, | ||||
| 0xa, | ||||
| 0x4, | ||||
| 0x5b, | ||||
| 0x81, | ||||
| 0xb, | ||||
| 0x50, | ||||
| 0x43, | ||||
| 0x49, | ||||
| 0x43, | ||||
| 0x3, | ||||
| 0x56, | ||||
| 0x45, | ||||
| 0x4e, | ||||
| 0x44, | ||||
| 0x20, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x31, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x32, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x19, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x33, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa0, | ||||
| 0xe, | ||||
| 0x93, | ||||
| 0x56, | ||||
| 0x45, | ||||
| 0x4e, | ||||
| 0x44, | ||||
| 0xc, | ||||
| 0x36, | ||||
| 0x1b, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xa4, | ||||
| 0xa, | ||||
| 0x3, | ||||
| 0xa1, | ||||
| 0x3, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x10, | ||||
| 0x25, | ||||
| 0x2e, | ||||
| 0x5f, | ||||
| @@ -860,7 +811,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x4e, | ||||
| 0x1, | ||||
| 0x10, | ||||
| 0x4b, | ||||
| 0x4a, | ||||
| 0x1e, | ||||
| 0x2f, | ||||
| 0x3, | ||||
| @@ -878,7 +829,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x5f, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2d, | ||||
| 0x2c, | ||||
| 0x53, | ||||
| 0x4d, | ||||
| 0x43, | ||||
| @@ -898,9 +849,8 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x53, | ||||
| 0x54, | ||||
| 0x41, | ||||
| 0xb, | ||||
| 0x0, | ||||
| 0xff, | ||||
| 0xa, | ||||
| 0xf0, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x43, | ||||
| @@ -4061,7 +4011,7 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x1, | ||||
| 0x10, | ||||
| 0x47, | ||||
| 0xe, | ||||
| 0x11, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x42, | ||||
| @@ -4291,6 +4241,54 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x3, | ||||
| 0x75, | ||||
| 0x60, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2e, | ||||
| 0x50, | ||||
| 0x52, | ||||
| 0x45, | ||||
| 0x53, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x48, | ||||
| 0x49, | ||||
| 0x44, | ||||
| 0xd, | ||||
| 0x41, | ||||
| 0x43, | ||||
| 0x50, | ||||
| 0x49, | ||||
| 0x30, | ||||
| 0x30, | ||||
| 0x30, | ||||
| 0x34, | ||||
| 0x0, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x43, | ||||
| 0x52, | ||||
| 0x53, | ||||
| 0x11, | ||||
| 0xd, | ||||
| 0xa, | ||||
| 0xa, | ||||
| 0x47, | ||||
| 0x1, | ||||
| 0x0, | ||||
| 0xaf, | ||||
| 0x0, | ||||
| 0xaf, | ||||
| 0x0, | ||||
| 0x20, | ||||
| 0x79, | ||||
| 0x0, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x54, | ||||
| 0x41, | ||||
| 0xa, | ||||
| 0xb, | ||||
| 0x10, | ||||
| 0x42, | ||||
| 0xc, | ||||
| @@ -4488,5 +4486,5 @@ static unsigned char AcpiDsdtAmlCode[] = { | ||||
| 0x0 | ||||
| }; | ||||
| static unsigned short piix_dsdt_applesmc_sta[] = { | ||||
| 0x384 | ||||
| 0x353 | ||||
| }; | ||||
|   | ||||
| @@ -72,6 +72,8 @@ DefinitionBlock ( | ||||
|             Name(_ADR, 0x00) | ||||
|             Name(_UID, 1) | ||||
|  | ||||
|             External(ISA, DeviceObj) | ||||
|  | ||||
|             // _OSC: based on sample of ACPI3.0b spec | ||||
|             Name(SUPP, 0) // PCI _OSC Support Field value | ||||
|             Name(CTRL, 0) // PCI _OSC Control Field value | ||||
| @@ -133,26 +135,6 @@ DefinitionBlock ( | ||||
| #include "acpi-dsdt-hpet.dsl" | ||||
|  | ||||
|  | ||||
| /**************************************************************** | ||||
|  * VGA | ||||
|  ****************************************************************/ | ||||
|  | ||||
|     Scope(\_SB.PCI0) { | ||||
|         Device(VGA) { | ||||
|             Name(_ADR, 0x00010000) | ||||
|             Method(_S1D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S2D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S3D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| /**************************************************************** | ||||
|  * LPC ISA bridge | ||||
|  ****************************************************************/ | ||||
| @@ -160,8 +142,7 @@ DefinitionBlock ( | ||||
|     Scope(\_SB.PCI0) { | ||||
|         /* PCI D31:f0 LPC ISA bridge */ | ||||
|         Device(ISA) { | ||||
|             /* PCI D31:f0 */ | ||||
|             Name(_ADR, 0x001f0000) | ||||
|             Name (_ADR, 0x001F0000)  // _ADR: Address | ||||
|  | ||||
|             /* ICH9 PCI to ISA irq remapping */ | ||||
|             OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C) | ||||
|   | ||||
| @@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x53, | ||||
| 0x44, | ||||
| 0x54, | ||||
| 0xdf, | ||||
| 0xd7, | ||||
| 0x1c, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xff, | ||||
| 0x3e, | ||||
| 0x42, | ||||
| 0x58, | ||||
| 0x50, | ||||
| @@ -415,11 +415,11 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xf7, | ||||
| 0xd7, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xf8, | ||||
| 0xd8, | ||||
| 0xc, | ||||
| 0x88, | ||||
| 0xd, | ||||
| @@ -853,61 +853,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x79, | ||||
| 0x0, | ||||
| 0x10, | ||||
| 0x36, | ||||
| 0x2e, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x42, | ||||
| 0x5f, | ||||
| 0x50, | ||||
| 0x43, | ||||
| 0x49, | ||||
| 0x30, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2a, | ||||
| 0x56, | ||||
| 0x47, | ||||
| 0x41, | ||||
| 0x5f, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x41, | ||||
| 0x44, | ||||
| 0x52, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x31, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x32, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x33, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x10, | ||||
| 0x4c, | ||||
| 0x7, | ||||
| 0x2e, | ||||
| @@ -1033,7 +978,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x4e, | ||||
| 0x1, | ||||
| 0x10, | ||||
| 0x4b, | ||||
| 0x4a, | ||||
| 0x1e, | ||||
| 0x2f, | ||||
| 0x3, | ||||
| @@ -1051,7 +996,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x5f, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2d, | ||||
| 0x2c, | ||||
| 0x53, | ||||
| 0x4d, | ||||
| 0x43, | ||||
| @@ -1071,9 +1016,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x53, | ||||
| 0x54, | ||||
| 0x41, | ||||
| 0xb, | ||||
| 0x0, | ||||
| 0xff, | ||||
| 0xa, | ||||
| 0xf0, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x43, | ||||
| @@ -7016,7 +6960,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x1, | ||||
| 0x10, | ||||
| 0x47, | ||||
| 0xe, | ||||
| 0x11, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x42, | ||||
| @@ -7121,8 +7065,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x54, | ||||
| 0x1, | ||||
| 0xb, | ||||
| 0x0, | ||||
| 0xaf, | ||||
| 0xd8, | ||||
| 0xc, | ||||
| 0xa, | ||||
| 0x20, | ||||
| 0x5b, | ||||
| @@ -7246,6 +7190,54 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x3, | ||||
| 0x75, | ||||
| 0x60, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2e, | ||||
| 0x50, | ||||
| 0x52, | ||||
| 0x45, | ||||
| 0x53, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x48, | ||||
| 0x49, | ||||
| 0x44, | ||||
| 0xd, | ||||
| 0x41, | ||||
| 0x43, | ||||
| 0x50, | ||||
| 0x49, | ||||
| 0x30, | ||||
| 0x30, | ||||
| 0x30, | ||||
| 0x34, | ||||
| 0x0, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x43, | ||||
| 0x52, | ||||
| 0x53, | ||||
| 0x11, | ||||
| 0xd, | ||||
| 0xa, | ||||
| 0xa, | ||||
| 0x47, | ||||
| 0x1, | ||||
| 0xd8, | ||||
| 0xc, | ||||
| 0xd8, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x20, | ||||
| 0x79, | ||||
| 0x0, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x54, | ||||
| 0x41, | ||||
| 0xa, | ||||
| 0xb, | ||||
| 0x10, | ||||
| 0x4f, | ||||
| 0x8, | ||||
| @@ -7392,5 +7384,5 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { | ||||
| 0x0 | ||||
| }; | ||||
| static unsigned short q35_dsdt_applesmc_sta[] = { | ||||
| 0x431 | ||||
| 0x3fa | ||||
| }; | ||||
|   | ||||
| @@ -46,5 +46,55 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         ACPI_EXTRACT_DEVICE_START ssdt_pcinohp_start | ||||
|         ACPI_EXTRACT_DEVICE_END ssdt_pcinohp_end | ||||
|         ACPI_EXTRACT_DEVICE_STRING ssdt_pcinohp_name | ||||
|  | ||||
|         // Extract the offsets of the device name, address dword and the slot | ||||
|         // name byte - we fill them in for each device. | ||||
|         Device(SBB) { | ||||
|             ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcinohp_adr | ||||
|             Name(_ADR, 0xAA0000) | ||||
|         } | ||||
|  | ||||
|         ACPI_EXTRACT_DEVICE_START ssdt_pcivga_start | ||||
|         ACPI_EXTRACT_DEVICE_END ssdt_pcivga_end | ||||
|         ACPI_EXTRACT_DEVICE_STRING ssdt_pcivga_name | ||||
|  | ||||
|         // Extract the offsets of the device name, address dword and the slot | ||||
|         // name byte - we fill them in for each device. | ||||
|         Device(SCC) { | ||||
|             ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcivga_adr | ||||
|             Name(_ADR, 0xAA0000) | ||||
|             Method(_S1D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S2D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S3D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         ACPI_EXTRACT_DEVICE_START ssdt_pciqxl_start | ||||
|         ACPI_EXTRACT_DEVICE_END ssdt_pciqxl_end | ||||
|         ACPI_EXTRACT_DEVICE_STRING ssdt_pciqxl_name | ||||
|  | ||||
|         // Extract the offsets of the device name, address dword and the slot | ||||
|         // name byte - we fill them in for each device. | ||||
|         Device(SDD) { | ||||
|             ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pciqxl_adr | ||||
|             Name(_ADR, 0xAA0000) | ||||
|             Method(_S1D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S2D, 0, NotSerialized) { | ||||
|                 Return (0x00) | ||||
|             } | ||||
|             Method(_S3D, 0, NotSerialized) { | ||||
|                 Return (0x03)           // QXL | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,23 +1,38 @@ | ||||
| static unsigned char ssdt_pcihp_name[] = { | ||||
| 0x33 | ||||
| 0x34 | ||||
| }; | ||||
| static unsigned char ssdt_pcivga_end[] = { | ||||
| 0x99 | ||||
| }; | ||||
| static unsigned char ssdt_pcivga_name[] = { | ||||
| 0x70 | ||||
| }; | ||||
| static unsigned char ssdt_pcihp_adr[] = { | ||||
| 0x44 | ||||
| 0x45 | ||||
| }; | ||||
| static unsigned char ssdt_pcinohp_end[] = { | ||||
| 0x6d | ||||
| }; | ||||
| static unsigned char ssdt_pcihp_end[] = { | ||||
| 0x5b | ||||
| 0x5c | ||||
| }; | ||||
| static unsigned char ssdt_pciqxl_start[] = { | ||||
| 0x99 | ||||
| }; | ||||
| static unsigned char ssdt_pcinohp_name[] = { | ||||
| 0x5f | ||||
| }; | ||||
| static unsigned char ssdp_pcihp_aml[] = { | ||||
| 0x53, | ||||
| 0x53, | ||||
| 0x44, | ||||
| 0x54, | ||||
| 0x5b, | ||||
| 0xc6, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0x1, | ||||
| 0xe8, | ||||
| 0x6b, | ||||
| 0x42, | ||||
| 0x58, | ||||
| 0x50, | ||||
| @@ -45,7 +60,8 @@ static unsigned char ssdp_pcihp_aml[] = { | ||||
| 0x13, | ||||
| 0x20, | ||||
| 0x10, | ||||
| 0x36, | ||||
| 0x41, | ||||
| 0xa, | ||||
| 0x5c, | ||||
| 0x2e, | ||||
| 0x5f, | ||||
| @@ -98,11 +114,138 @@ static unsigned char ssdp_pcihp_aml[] = { | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x55, | ||||
| 0x4e | ||||
| 0x4e, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0xf, | ||||
| 0x53, | ||||
| 0x42, | ||||
| 0x42, | ||||
| 0x5f, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x41, | ||||
| 0x44, | ||||
| 0x52, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xaa, | ||||
| 0x0, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2a, | ||||
| 0x53, | ||||
| 0x43, | ||||
| 0x43, | ||||
| 0x5f, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x41, | ||||
| 0x44, | ||||
| 0x52, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xaa, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x31, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x32, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x33, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x5b, | ||||
| 0x82, | ||||
| 0x2b, | ||||
| 0x53, | ||||
| 0x44, | ||||
| 0x44, | ||||
| 0x5f, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x41, | ||||
| 0x44, | ||||
| 0x52, | ||||
| 0xc, | ||||
| 0x0, | ||||
| 0x0, | ||||
| 0xaa, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x31, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x8, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x32, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0x0, | ||||
| 0x14, | ||||
| 0x9, | ||||
| 0x5f, | ||||
| 0x53, | ||||
| 0x33, | ||||
| 0x44, | ||||
| 0x0, | ||||
| 0xa4, | ||||
| 0xa, | ||||
| 0x3 | ||||
| }; | ||||
| static unsigned char ssdt_pciqxl_adr[] = { | ||||
| 0xa6 | ||||
| }; | ||||
| static unsigned char ssdt_pcinohp_adr[] = { | ||||
| 0x69 | ||||
| }; | ||||
| static unsigned char ssdt_pcivga_adr[] = { | ||||
| 0x7a | ||||
| }; | ||||
| static unsigned char ssdt_pciqxl_name[] = { | ||||
| 0x9c | ||||
| }; | ||||
| static unsigned char ssdt_pcivga_start[] = { | ||||
| 0x6d | ||||
| }; | ||||
| static unsigned char ssdt_pciqxl_end[] = { | ||||
| 0xc6 | ||||
| }; | ||||
| static unsigned char ssdt_pcihp_start[] = { | ||||
| 0x30 | ||||
| 0x31 | ||||
| }; | ||||
| static unsigned char ssdt_pcihp_id[] = { | ||||
| 0x3d | ||||
| 0x3e | ||||
| }; | ||||
| static unsigned char ssdt_pcinohp_start[] = { | ||||
| 0x5c | ||||
| }; | ||||
|   | ||||
| @@ -281,7 +281,7 @@ static void kbd_write_command(void *opaque, hwaddr addr, | ||||
|         kbd_update_irq(s); | ||||
|         break; | ||||
|     case KBD_CCMD_READ_INPORT: | ||||
|         kbd_queue(s, 0x00, 0); | ||||
|         kbd_queue(s, 0x80, 0); | ||||
|         break; | ||||
|     case KBD_CCMD_READ_OUTPORT: | ||||
|         kbd_queue(s, s->outport, 0); | ||||
|   | ||||
| @@ -93,9 +93,6 @@ static void ioapic_set_irq(void *opaque, int vector, int level) | ||||
|         uint32_t mask = 1 << vector; | ||||
|         uint64_t entry = s->ioredtbl[vector]; | ||||
|  | ||||
|         if (entry & (1 << IOAPIC_LVT_POLARITY_SHIFT)) { | ||||
|             level = !level; | ||||
|         } | ||||
|         if (((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1) == | ||||
|             IOAPIC_TRIGGER_LEVEL) { | ||||
|             /* level triggered */ | ||||
|   | ||||
| @@ -397,12 +397,15 @@ static int peer_detach(VirtIONet *n, int index) | ||||
| static void virtio_net_set_queues(VirtIONet *n) | ||||
| { | ||||
|     int i; | ||||
|     int r; | ||||
|  | ||||
|     for (i = 0; i < n->max_queues; i++) { | ||||
|         if (i < n->curr_queues) { | ||||
|             assert(!peer_attach(n, i)); | ||||
|             r = peer_attach(n, i); | ||||
|             assert(!r); | ||||
|         } else { | ||||
|             assert(!peer_detach(n, i)); | ||||
|             r = peer_detach(n, i); | ||||
|             assert(!r); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -68,7 +68,7 @@ void init_pam(DeviceState *dev, MemoryRegion *ram_memory, | ||||
|     /* XXX: should distinguish read/write cases */ | ||||
|     memory_region_init_alias(&mem->alias[0], OBJECT(dev), "pam-pci", pci_address_space, | ||||
|                              start, size); | ||||
|     memory_region_init_alias(&mem->alias[2], OBJECT(dev), "pam-pci", pci_address_space, | ||||
|     memory_region_init_alias(&mem->alias[2], OBJECT(dev), "pam-pci", ram_memory, | ||||
|                              start, size); | ||||
|  | ||||
|     for (i = 0; i < 4; ++i) { | ||||
|   | ||||
| @@ -221,29 +221,23 @@ static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev, | ||||
|                                          DeviceState *dev, | ||||
|                                          uint8_t **exp_cap, Error **errp) | ||||
| { | ||||
|     PCIDevice *pci_dev = PCI_DEVICE(dev); | ||||
|     *exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap; | ||||
|     uint16_t sltsta = pci_get_word(*exp_cap + PCI_EXP_SLTSTA); | ||||
|  | ||||
|     PCIE_DEV_PRINTF(pci_dev, "hotplug state: %d\n", state); | ||||
|     PCIE_DEV_PRINTF(PCI_DEVICE(dev), "hotplug state: %d\n", state); | ||||
|     if (sltsta & PCI_EXP_SLTSTA_EIS) { | ||||
|         /* the slot is electromechanically locked. | ||||
|          * This error is propagated up to qdev and then to HMP/QMP. | ||||
|          */ | ||||
|         error_setg_errno(errp, -EBUSY, "slot is electromechanically locked"); | ||||
|     } | ||||
|  | ||||
|     /* TODO: multifunction hot-plug. | ||||
|      * Right now, only a device of function = 0 is allowed to be | ||||
|      * hot plugged/unplugged. | ||||
|      */ | ||||
|     assert(PCI_FUNC(pci_dev->devfn) == 0); | ||||
| } | ||||
|  | ||||
| void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, | ||||
|                               Error **errp) | ||||
| { | ||||
|     uint8_t *exp_cap; | ||||
|     PCIDevice *pci_dev = PCI_DEVICE(dev); | ||||
|  | ||||
|     pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp); | ||||
|  | ||||
| @@ -256,6 +250,12 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /* TODO: multifunction hot-plug. | ||||
|      * Right now, only a device of function = 0 is allowed to be | ||||
|      * hot plugged/unplugged. | ||||
|      */ | ||||
|     assert(PCI_FUNC(pci_dev->devfn) == 0); | ||||
|  | ||||
|     pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, | ||||
|                                PCI_EXP_SLTSTA_PDS); | ||||
|     pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC); | ||||
|   | ||||
| @@ -43,7 +43,7 @@ | ||||
|  | ||||
| /* config register */ | ||||
| #define R_CONFIG            (0x00 / 4) | ||||
| #define IFMODE              (1 << 31) | ||||
| #define IFMODE              (1U << 31) | ||||
| #define ENDIAN              (1 << 26) | ||||
| #define MODEFAIL_GEN_EN     (1 << 17) | ||||
| #define MAN_START_COM       (1 << 16) | ||||
| @@ -87,7 +87,7 @@ | ||||
|  | ||||
| #define R_LQSPI_CFG         (0xa0 / 4) | ||||
| #define R_LQSPI_CFG_RESET       0x03A002EB | ||||
| #define LQSPI_CFG_LQ_MODE       (1 << 31) | ||||
| #define LQSPI_CFG_LQ_MODE       (1U << 31) | ||||
| #define LQSPI_CFG_TWO_MEM       (1 << 30) | ||||
| #define LQSPI_CFG_SEP_BUS       (1 << 30) | ||||
| #define LQSPI_CFG_U_PAGE        (1 << 28) | ||||
|   | ||||
| @@ -546,10 +546,10 @@ static int emulated_initfn(CCIDCardState *base) | ||||
|         printf("%s: failed to initialize vcard\n", EMULATED_DEV_NAME); | ||||
|         return -1; | ||||
|     } | ||||
|     qemu_thread_create(&card->event_thread_id, event_thread, card, | ||||
|                        QEMU_THREAD_JOINABLE); | ||||
|     qemu_thread_create(&card->apdu_thread_id, handle_apdu_thread, card, | ||||
|                        QEMU_THREAD_JOINABLE); | ||||
|     qemu_thread_create(&card->event_thread_id, "ccid/event", event_thread, | ||||
|                        card, QEMU_THREAD_JOINABLE); | ||||
|     qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thread, | ||||
|                        card, QEMU_THREAD_JOINABLE); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -59,6 +59,7 @@ typedef uint64_t target_ulong; | ||||
| #define EXCP_HLT        0x10001 /* hlt instruction reached */ | ||||
| #define EXCP_DEBUG      0x10002 /* cpu stopped after a breakpoint or singlestep */ | ||||
| #define EXCP_HALTED     0x10003 /* cpu is halted (waiting for external event) */ | ||||
| #define EXCP_YIELD      0x10004 /* cpu wants to yield timeslice to another */ | ||||
|  | ||||
| #define TB_JMP_CACHE_BITS 12 | ||||
| #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) | ||||
|   | ||||
| @@ -836,13 +836,13 @@ void memory_region_set_alias_offset(MemoryRegion *mr, | ||||
|                                     hwaddr offset); | ||||
|  | ||||
| /** | ||||
|  * memory_region_present: translate an address/size relative to a | ||||
|  * MemoryRegion into a #MemoryRegionSection. | ||||
|  * memory_region_present: checks if an address relative to a @parent | ||||
|  * translates into #MemoryRegion within @parent | ||||
|  * | ||||
|  * Answer whether a #MemoryRegion within @parent covers the address | ||||
|  * @addr. | ||||
|  * | ||||
|  * @parent: a MemoryRegion within which @addr is a relative address | ||||
|  * @parent: a #MemoryRegion within which @addr is a relative address | ||||
|  * @addr: the area within @parent to be searched | ||||
|  */ | ||||
| bool memory_region_present(MemoryRegion *parent, hwaddr addr); | ||||
|   | ||||
| @@ -52,12 +52,13 @@ void qemu_event_reset(QemuEvent *ev); | ||||
| void qemu_event_wait(QemuEvent *ev); | ||||
| void qemu_event_destroy(QemuEvent *ev); | ||||
|  | ||||
| void qemu_thread_create(QemuThread *thread, | ||||
| void qemu_thread_create(QemuThread *thread, const char *name, | ||||
|                         void *(*start_routine)(void *), | ||||
|                         void *arg, int mode); | ||||
| void *qemu_thread_join(QemuThread *thread); | ||||
| void qemu_thread_get_self(QemuThread *thread); | ||||
| bool qemu_thread_is_self(QemuThread *thread); | ||||
| void qemu_thread_exit(void *retval); | ||||
| void qemu_thread_naming(bool enable); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1423,11 +1423,10 @@ int kvm_init(QEMUMachine *machine) | ||||
|                     nc->name, nc->num, soft_vcpus_limit); | ||||
|  | ||||
|             if (nc->num > hard_vcpus_limit) { | ||||
|                 ret = -EINVAL; | ||||
|                 fprintf(stderr, "Number of %s cpus requested (%d) exceeds " | ||||
|                         "the maximum cpus supported by KVM (%d)\n", | ||||
|                         nc->name, nc->num, hard_vcpus_limit); | ||||
|                 goto err; | ||||
|                 exit(1); | ||||
|             } | ||||
|         } | ||||
|         nc++; | ||||
|   | ||||
| @@ -269,7 +269,7 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) | ||||
|     send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); | ||||
|     /* launch the event_thread. This will trigger reader adds for all the | ||||
|      * existing readers */ | ||||
|     qemu_thread_create(&thread_id, event_thread, NULL, 0); | ||||
|     qemu_thread_create(&thread_id, "vsc/event", event_thread, NULL, 0); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ struct target_pt_regs { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "alpha" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #undef TARGET_EDEADLK | ||||
| #define TARGET_EDEADLK		11 | ||||
|   | ||||
| @@ -40,5 +40,6 @@ struct target_pt_regs { | ||||
| #else | ||||
| #define UNAME_MACHINE "armv5tel" | ||||
| #endif | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_CLONE_BACKWARDS | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #ifndef CRIS_SYSCALL_H | ||||
| #define CRIS_SYSCALL_H 1 | ||||
|  | ||||
|  | ||||
| #define UNAME_MACHINE "cris" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| /* pt_regs not only specifices the format in the user-struct during | ||||
|  * ptrace but is also the frame format used in the kernel prologue/epilogues | ||||
|   | ||||
| @@ -144,5 +144,6 @@ struct target_vm86plus_struct { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "i686" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_CLONE_BACKWARDS | ||||
|   | ||||
| @@ -15,7 +15,7 @@ struct target_pt_regs { | ||||
|     uint16_t __fill; | ||||
| }; | ||||
|  | ||||
|  | ||||
| #define UNAME_MACHINE "m68k" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| void do_m68k_simcall(CPUM68KState *, int); | ||||
|   | ||||
| @@ -2400,6 +2400,10 @@ static int do_break(CPUMIPSState *env, target_siginfo_t *info, | ||||
|         ret = 0; | ||||
|         break; | ||||
|     default: | ||||
|         info->si_signo = TARGET_SIGTRAP; | ||||
|         info->si_errno = 0; | ||||
|         queue_signal(env, info->si_signo, &*info); | ||||
|         ret = 0; | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #ifndef MICROBLAZE_SYSCALLS_H | ||||
| #define MICROBLAZE_SYSCALLS_H 1 | ||||
|  | ||||
|  | ||||
| #define UNAME_MACHINE "microblaze" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| /* We use microblaze_reg_t to keep things similar to the kernel sources.  */ | ||||
| typedef uint32_t microblaze_reg_t; | ||||
|   | ||||
| @@ -225,5 +225,6 @@ struct target_pt_regs { | ||||
| #define TARGET_QEMU_ESIGRETURN 255 | ||||
|  | ||||
| #define UNAME_MACHINE "mips" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_CLONE_BACKWARDS | ||||
|   | ||||
| @@ -222,5 +222,6 @@ struct target_pt_regs { | ||||
| #define TARGET_QEMU_ESIGRETURN 255 | ||||
|  | ||||
| #define UNAME_MACHINE "mips64" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_CLONE_BACKWARDS | ||||
|   | ||||
| @@ -22,3 +22,4 @@ struct target_pt_regs { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "openrisc" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|   | ||||
| @@ -62,5 +62,6 @@ struct target_revectored_struct { | ||||
| #else | ||||
| #define UNAME_MACHINE "ppc" | ||||
| #endif | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_CLONE_BACKWARDS | ||||
|   | ||||
| @@ -21,5 +21,6 @@ struct target_pt_regs { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "s390x" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_CLONE_BACKWARDS2 | ||||
|   | ||||
| @@ -10,3 +10,4 @@ struct target_pt_regs { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "sh4" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|   | ||||
| @@ -1233,8 +1233,14 @@ static int target_restore_sigframe(CPUARMState *env, | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < 32 * 2; i++) { | ||||
|         __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]); | ||||
|     for (i = 0; i < 32; i++) { | ||||
| #ifdef TARGET_WORDS_BIGENDIAN | ||||
|         __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]); | ||||
|         __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]); | ||||
| #else | ||||
|         __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]); | ||||
|         __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]); | ||||
| #endif | ||||
|     } | ||||
|     __get_user(fpsr, &aux->fpsimd.fpsr); | ||||
|     vfp_set_fpsr(env, fpsr); | ||||
| @@ -1267,7 +1273,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka, | ||||
|                                CPUARMState *env) | ||||
| { | ||||
|     struct target_rt_sigframe *frame; | ||||
|     abi_ulong frame_addr; | ||||
|     abi_ulong frame_addr, return_addr; | ||||
|  | ||||
|     frame_addr = get_sigframe(ka, env); | ||||
|     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { | ||||
| @@ -1284,15 +1290,19 @@ static void target_setup_frame(int usig, struct target_sigaction *ka, | ||||
|     __put_user(target_sigaltstack_used.ss_size, | ||||
|                       &frame->uc.tuc_stack.ss_size); | ||||
|     target_setup_sigframe(frame, env, set); | ||||
|     /* mov x8,#__NR_rt_sigreturn; svc #0 */ | ||||
|     __put_user(0xd2801168, &frame->tramp[0]); | ||||
|     __put_user(0xd4000001, &frame->tramp[1]); | ||||
|     if (ka->sa_flags & TARGET_SA_RESTORER) { | ||||
|         return_addr = ka->sa_restorer; | ||||
|     } else { | ||||
|         /* mov x8,#__NR_rt_sigreturn; svc #0 */ | ||||
|         __put_user(0xd2801168, &frame->tramp[0]); | ||||
|         __put_user(0xd4000001, &frame->tramp[1]); | ||||
|         return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp); | ||||
|     } | ||||
|     env->xregs[0] = usig; | ||||
|     env->xregs[31] = frame_addr; | ||||
|     env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp); | ||||
|     env->pc = ka->_sa_handler; | ||||
|     env->xregs[30] = env->xregs[31] + | ||||
|         offsetof(struct target_rt_sigframe, tramp); | ||||
|     env->xregs[30] = return_addr; | ||||
|     if (info) { | ||||
|         if (copy_siginfo_to_user(&frame->info, info)) { | ||||
|             goto give_sigsegv; | ||||
|   | ||||
| @@ -7,6 +7,7 @@ struct target_pt_regs { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "sun4" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| /* SPARC kernels don't define this in their Kconfig, but they have the | ||||
|  * same ABI as if they did, implemented by sparc-specific code which fishes | ||||
|   | ||||
| @@ -8,6 +8,7 @@ struct target_pt_regs { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "sun4u" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| /* SPARC kernels don't define this in their Kconfig, but they have the | ||||
|  * same ABI as if they did, implemented by sparc-specific code which fishes | ||||
|   | ||||
| @@ -1904,23 +1904,16 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, | ||||
|     return get_errno(connect(sockfd, addr, addrlen)); | ||||
| } | ||||
|  | ||||
| /* do_sendrecvmsg() Must return target values and target errnos. */ | ||||
| static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, | ||||
|                                int flags, int send) | ||||
| /* do_sendrecvmsg_locked() Must return target values and target errnos. */ | ||||
| static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, | ||||
|                                       int flags, int send) | ||||
| { | ||||
|     abi_long ret, len; | ||||
|     struct target_msghdr *msgp; | ||||
|     struct msghdr msg; | ||||
|     int count; | ||||
|     struct iovec *vec; | ||||
|     abi_ulong target_vec; | ||||
|  | ||||
|     /* FIXME */ | ||||
|     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, | ||||
|                           msgp, | ||||
|                           target_msg, | ||||
|                           send ? 1 : 0)) | ||||
|         return -TARGET_EFAULT; | ||||
|     if (msgp->msg_name) { | ||||
|         msg.msg_namelen = tswap32(msgp->msg_namelen); | ||||
|         msg.msg_name = alloca(msg.msg_namelen); | ||||
| @@ -1975,10 +1968,75 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, | ||||
| out: | ||||
|     unlock_iovec(vec, target_vec, count, !send); | ||||
| out2: | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, | ||||
|                                int flags, int send) | ||||
| { | ||||
|     abi_long ret; | ||||
|     struct target_msghdr *msgp; | ||||
|  | ||||
|     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, | ||||
|                           msgp, | ||||
|                           target_msg, | ||||
|                           send ? 1 : 0)) { | ||||
|         return -TARGET_EFAULT; | ||||
|     } | ||||
|     ret = do_sendrecvmsg_locked(fd, msgp, flags, send); | ||||
|     unlock_user_struct(msgp, target_msg, send ? 0 : 1); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| #ifdef TARGET_NR_sendmmsg | ||||
| /* We don't rely on the C library to have sendmmsg/recvmmsg support, | ||||
|  * so it might not have this *mmsg-specific flag either. | ||||
|  */ | ||||
| #ifndef MSG_WAITFORONE | ||||
| #define MSG_WAITFORONE 0x10000 | ||||
| #endif | ||||
|  | ||||
| static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec, | ||||
|                                 unsigned int vlen, unsigned int flags, | ||||
|                                 int send) | ||||
| { | ||||
|     struct target_mmsghdr *mmsgp; | ||||
|     abi_long ret = 0; | ||||
|     int i; | ||||
|  | ||||
|     if (vlen > UIO_MAXIOV) { | ||||
|         vlen = UIO_MAXIOV; | ||||
|     } | ||||
|  | ||||
|     mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1); | ||||
|     if (!mmsgp) { | ||||
|         return -TARGET_EFAULT; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < vlen; i++) { | ||||
|         ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send); | ||||
|         if (is_error(ret)) { | ||||
|             break; | ||||
|         } | ||||
|         mmsgp[i].msg_len = tswap32(ret); | ||||
|         /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ | ||||
|         if (flags & MSG_WAITFORONE) { | ||||
|             flags |= MSG_DONTWAIT; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i); | ||||
|  | ||||
|     /* Return number of datagrams sent if we sent any at all; | ||||
|      * otherwise return the error. | ||||
|      */ | ||||
|     if (i) { | ||||
|         return i; | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* If we don't have a system accept4() then just call accept. | ||||
|  * The callsites to do_accept4() will ensure that they don't | ||||
|  * pass a non-zero flags argument in this config. | ||||
| @@ -4528,6 +4586,9 @@ static inline int tswapid(int id) | ||||
| { | ||||
|     return tswap16(id); | ||||
| } | ||||
|  | ||||
| #define put_user_id(x, gaddr) put_user_u16(x, gaddr) | ||||
|  | ||||
| #else /* !USE_UID16 */ | ||||
| static inline int high2lowuid(int uid) | ||||
| { | ||||
| @@ -4549,6 +4610,9 @@ static inline int tswapid(int id) | ||||
| { | ||||
|     return tswap32(id); | ||||
| } | ||||
|  | ||||
| #define put_user_id(x, gaddr) put_user_u32(x, gaddr) | ||||
|  | ||||
| #endif /* USE_UID16 */ | ||||
|  | ||||
| void syscall_init(void) | ||||
| @@ -6121,11 +6185,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||||
|                 puts = NULL; | ||||
|             } | ||||
|             ret = get_errno(sigtimedwait(&set, &uinfo, puts)); | ||||
|             if (!is_error(ret) && arg2) { | ||||
|                 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0))) | ||||
|                     goto efault; | ||||
|                 host_to_target_siginfo(p, &uinfo); | ||||
|                 unlock_user(p, arg2, sizeof(target_siginfo_t)); | ||||
|             if (!is_error(ret)) { | ||||
|                 if (arg2) { | ||||
|                     p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), | ||||
|                                   0); | ||||
|                     if (!p) { | ||||
|                         goto efault; | ||||
|                     } | ||||
|                     host_to_target_siginfo(p, &uinfo); | ||||
|                     unlock_user(p, arg2, sizeof(target_siginfo_t)); | ||||
|                 } | ||||
|                 ret = host_to_target_signal(ret); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
| @@ -6710,6 +6780,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||||
|         ret = do_sendrecvmsg(arg1, arg2, arg3, 1); | ||||
|         break; | ||||
| #endif | ||||
| #ifdef TARGET_NR_sendmmsg | ||||
|     case TARGET_NR_sendmmsg: | ||||
|         ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1); | ||||
|         break; | ||||
|     case TARGET_NR_recvmmsg: | ||||
|         ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0); | ||||
|         break; | ||||
| #endif | ||||
| #ifdef TARGET_NR_sendto | ||||
|     case TARGET_NR_sendto: | ||||
|         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6); | ||||
| @@ -7805,9 +7883,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||||
|             uid_t ruid, euid, suid; | ||||
|             ret = get_errno(getresuid(&ruid, &euid, &suid)); | ||||
|             if (!is_error(ret)) { | ||||
|                 if (put_user_u16(high2lowuid(ruid), arg1) | ||||
|                     || put_user_u16(high2lowuid(euid), arg2) | ||||
|                     || put_user_u16(high2lowuid(suid), arg3)) | ||||
|                 if (put_user_id(high2lowuid(ruid), arg1) | ||||
|                     || put_user_id(high2lowuid(euid), arg2) | ||||
|                     || put_user_id(high2lowuid(suid), arg3)) | ||||
|                     goto efault; | ||||
|             } | ||||
|         } | ||||
| @@ -7826,9 +7904,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||||
|             gid_t rgid, egid, sgid; | ||||
|             ret = get_errno(getresgid(&rgid, &egid, &sgid)); | ||||
|             if (!is_error(ret)) { | ||||
|                 if (put_user_u16(high2lowgid(rgid), arg1) | ||||
|                     || put_user_u16(high2lowgid(egid), arg2) | ||||
|                     || put_user_u16(high2lowgid(sgid), arg3)) | ||||
|                 if (put_user_id(high2lowgid(rgid), arg1) | ||||
|                     || put_user_id(high2lowgid(egid), arg2) | ||||
|                     || put_user_id(high2lowgid(sgid), arg3)) | ||||
|                     goto efault; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -53,7 +53,8 @@ | ||||
| #define TARGET_IOC_NRBITS	8 | ||||
| #define TARGET_IOC_TYPEBITS	8 | ||||
|  | ||||
| #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ | ||||
| #if defined(TARGET_I386) || (defined(TARGET_ARM) && defined(TARGET_ABI32)) \ | ||||
|     || defined(TARGET_SPARC) \ | ||||
|     || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) | ||||
|     /* 16 bit uid wrappers emulation */ | ||||
| #define USE_UID16 | ||||
| @@ -239,6 +240,10 @@ __target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr *__cms | ||||
|   return __cmsg; | ||||
| } | ||||
|  | ||||
| struct target_mmsghdr { | ||||
|     struct target_msghdr msg_hdr;              /* Message header */ | ||||
|     unsigned int         msg_len;              /* Number of bytes transmitted */ | ||||
| }; | ||||
|  | ||||
| struct  target_rusage { | ||||
|         struct target_timeval ru_utime;        /* user time used */ | ||||
|   | ||||
| @@ -51,5 +51,6 @@ struct target_pt_regs { | ||||
| #define UC32_SYSCALL_NR_set_tls         (UC32_SYSCALL_ARCH_BASE + 5) | ||||
|  | ||||
| #define UNAME_MACHINE "UniCore-II" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #endif /* __UC32_SYSCALL_H__ */ | ||||
|   | ||||
| @@ -91,6 +91,7 @@ struct target_msqid64_ds { | ||||
| }; | ||||
|  | ||||
| #define UNAME_MACHINE "x86_64" | ||||
| #define UNAME_MINIMUM_RELEASE "2.6.32" | ||||
|  | ||||
| #define TARGET_ARCH_SET_GS 0x1001 | ||||
| #define TARGET_ARCH_SET_FS 0x1002 | ||||
|   | ||||
							
								
								
									
										2
									
								
								memory.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								memory.c
									
									
									
									
									
								
							| @@ -1562,7 +1562,7 @@ static FlatRange *flatview_lookup(FlatView *view, AddrRange addr) | ||||
| bool memory_region_present(MemoryRegion *parent, hwaddr addr) | ||||
| { | ||||
|     MemoryRegion *mr = memory_region_find(parent, addr, 1).mr; | ||||
|     if (!mr) { | ||||
|     if (!mr || (mr == parent)) { | ||||
|         return false; | ||||
|     } | ||||
|     memory_region_unref(mr); | ||||
|   | ||||
| @@ -695,6 +695,6 @@ void migrate_fd_connect(MigrationState *s) | ||||
|     /* Notify before starting migration thread */ | ||||
|     notifier_list_notify(&migration_state_notifiers, s); | ||||
|  | ||||
|     qemu_thread_create(&s->thread, migration_thread, s, | ||||
|     qemu_thread_create(&s->thread, "migration", migration_thread, s, | ||||
|                        QEMU_THREAD_JOINABLE); | ||||
| } | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|   1275-1994 (referred to as Open Firmware) compliant firmware. | ||||
|   The included images for PowerPC (for 32 and 64 bit PPC CPUs), | ||||
|   Sparc32 (including QEMU,tcx.bin and QEMU,cgthree.bin) and Sparc64 are built | ||||
|   from OpenBIOS SVN revision 1246. | ||||
|   from OpenBIOS SVN revision 1280. | ||||
|  | ||||
| - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware | ||||
|   implementation for certain IBM POWER hardware.  The sources are at | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -105,7 +105,7 @@ static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, | ||||
|     res = fwrite(buf, 1, size, s->stdio_file); | ||||
|  | ||||
|     if (res != size) { | ||||
|         return -EIO;	/* fake errno value */ | ||||
|         return -errno; | ||||
|     } | ||||
|     return res; | ||||
| } | ||||
|   | ||||
| @@ -328,9 +328,11 @@ possible drivers and properties, use @code{-device help} and | ||||
| ETEXI | ||||
|  | ||||
| DEF("name", HAS_ARG, QEMU_OPTION_name, | ||||
|     "-name string1[,process=string2]\n" | ||||
|     "-name string1[,process=string2][,debug-threads=on|off]\n" | ||||
|     "                set the name of the guest\n" | ||||
|     "                string1 sets the window title and string2 the process name (on Linux)\n", | ||||
|     "                string1 sets the window title and string2 the process name (on Linux)\n" | ||||
|     "                When debug-threads is enabled, individual threads are given a separate name (on Linux)\n" | ||||
|     "                NOTE: The thread names are for debugging and not a stable API.\n", | ||||
|     QEMU_ARCH_ALL) | ||||
| STEXI | ||||
| @item -name @var{name} | ||||
| @@ -339,6 +341,7 @@ Sets the @var{name} of the guest. | ||||
| This name will be displayed in the SDL window caption. | ||||
| The @var{name} will also be used for the VNC server. | ||||
| Also optionally set the top visible process name in Linux. | ||||
| Naming of individual threads can also be enabled on Linux to aid debugging. | ||||
| ETEXI | ||||
|  | ||||
| DEF("uuid", HAS_ARG, QEMU_OPTION_uuid, | ||||
|   | ||||
 Submodule roms/openbios updated: 888126272f...1ac3fb92c1
									
								
							
							
								
								
									
										12
									
								
								savevm.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								savevm.c
									
									
									
									
									
								
							| @@ -527,13 +527,13 @@ int qemu_savevm_state_iterate(QEMUFile *f) | ||||
|         if (qemu_file_rate_limit(f)) { | ||||
|             return 0; | ||||
|         } | ||||
|         trace_savevm_section_start(); | ||||
|         trace_savevm_section_start(se->idstr, se->section_id); | ||||
|         /* Section type */ | ||||
|         qemu_put_byte(f, QEMU_VM_SECTION_PART); | ||||
|         qemu_put_be32(f, se->section_id); | ||||
|  | ||||
|         ret = se->ops->save_live_iterate(f, se->opaque); | ||||
|         trace_savevm_section_end(se->section_id); | ||||
|         trace_savevm_section_end(se->idstr, se->section_id); | ||||
|  | ||||
|         if (ret < 0) { | ||||
|             qemu_file_set_error(f, ret); | ||||
| @@ -565,13 +565,13 @@ void qemu_savevm_state_complete(QEMUFile *f) | ||||
|                 continue; | ||||
|             } | ||||
|         } | ||||
|         trace_savevm_section_start(); | ||||
|         trace_savevm_section_start(se->idstr, se->section_id); | ||||
|         /* Section type */ | ||||
|         qemu_put_byte(f, QEMU_VM_SECTION_END); | ||||
|         qemu_put_be32(f, se->section_id); | ||||
|  | ||||
|         ret = se->ops->save_live_complete(f, se->opaque); | ||||
|         trace_savevm_section_end(se->section_id); | ||||
|         trace_savevm_section_end(se->idstr, se->section_id); | ||||
|         if (ret < 0) { | ||||
|             qemu_file_set_error(f, ret); | ||||
|             return; | ||||
| @@ -584,7 +584,7 @@ void qemu_savevm_state_complete(QEMUFile *f) | ||||
|         if ((!se->ops || !se->ops->save_state) && !se->vmsd) { | ||||
|             continue; | ||||
|         } | ||||
|         trace_savevm_section_start(); | ||||
|         trace_savevm_section_start(se->idstr, se->section_id); | ||||
|         /* Section type */ | ||||
|         qemu_put_byte(f, QEMU_VM_SECTION_FULL); | ||||
|         qemu_put_be32(f, se->section_id); | ||||
| @@ -598,7 +598,7 @@ void qemu_savevm_state_complete(QEMUFile *f) | ||||
|         qemu_put_be32(f, se->version_id); | ||||
|  | ||||
|         vmstate_save(f, se); | ||||
|         trace_savevm_section_end(se->section_id); | ||||
|         trace_savevm_section_end(se->idstr, se->section_id); | ||||
|     } | ||||
|  | ||||
|     qemu_put_byte(f, QEMU_VM_EOF); | ||||
|   | ||||
| @@ -222,6 +222,10 @@ typedef struct CPUARMState { | ||||
|         uint64_t dbgbcr[16]; /* breakpoint control registers */ | ||||
|         uint64_t dbgwvr[16]; /* watchpoint value registers */ | ||||
|         uint64_t dbgwcr[16]; /* watchpoint control registers */ | ||||
|         /* If the counter is enabled, this stores the last time the counter | ||||
|          * was reset. Otherwise it stores the counter value | ||||
|          */ | ||||
|         uint32_t c15_ccnt; | ||||
|     } cp15; | ||||
|  | ||||
|     struct { | ||||
|   | ||||
| @@ -13,6 +13,11 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address, | ||||
|                                 int access_type, int is_user, | ||||
|                                 hwaddr *phys_ptr, int *prot, | ||||
|                                 target_ulong *page_size); | ||||
|  | ||||
| /* Definitions for the PMCCNTR and PMCR registers */ | ||||
| #define PMCRD   0x8 | ||||
| #define PMCRC   0x4 | ||||
| #define PMCRE   0x1 | ||||
| #endif | ||||
|  | ||||
| static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) | ||||
| @@ -478,14 +483,85 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri) | ||||
|     return CP_ACCESS_OK; | ||||
| } | ||||
|  | ||||
| #ifndef CONFIG_USER_ONLY | ||||
| static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||||
|                        uint64_t value) | ||||
| { | ||||
|     /* Don't computer the number of ticks in user mode */ | ||||
|     uint32_t temp_ticks; | ||||
|  | ||||
|     temp_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) * | ||||
|                   get_ticks_per_sec() / 1000000; | ||||
|  | ||||
|     if (env->cp15.c9_pmcr & PMCRE) { | ||||
|         /* If the counter is enabled */ | ||||
|         if (env->cp15.c9_pmcr & PMCRD) { | ||||
|             /* Increment once every 64 processor clock cycles */ | ||||
|             env->cp15.c15_ccnt = (temp_ticks/64) - env->cp15.c15_ccnt; | ||||
|         } else { | ||||
|             env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (value & PMCRC) { | ||||
|         /* The counter has been reset */ | ||||
|         env->cp15.c15_ccnt = 0; | ||||
|     } | ||||
|  | ||||
|     /* only the DP, X, D and E bits are writable */ | ||||
|     env->cp15.c9_pmcr &= ~0x39; | ||||
|     env->cp15.c9_pmcr |= (value & 0x39); | ||||
|  | ||||
|     if (env->cp15.c9_pmcr & PMCRE) { | ||||
|         if (env->cp15.c9_pmcr & PMCRD) { | ||||
|             /* Increment once every 64 processor clock cycles */ | ||||
|             temp_ticks /= 64; | ||||
|         } | ||||
|         env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||||
| { | ||||
|     uint32_t total_ticks; | ||||
|  | ||||
|     if (!(env->cp15.c9_pmcr & PMCRE)) { | ||||
|         /* Counter is disabled, do not change value */ | ||||
|         return env->cp15.c15_ccnt; | ||||
|     } | ||||
|  | ||||
|     total_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) * | ||||
|                   get_ticks_per_sec() / 1000000; | ||||
|  | ||||
|     if (env->cp15.c9_pmcr & PMCRD) { | ||||
|         /* Increment once every 64 processor clock cycles */ | ||||
|         total_ticks /= 64; | ||||
|     } | ||||
|     return total_ticks - env->cp15.c15_ccnt; | ||||
| } | ||||
|  | ||||
| static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||||
|                         uint64_t value) | ||||
| { | ||||
|     uint32_t total_ticks; | ||||
|  | ||||
|     if (!(env->cp15.c9_pmcr & PMCRE)) { | ||||
|         /* Counter is disabled, set the absolute value */ | ||||
|         env->cp15.c15_ccnt = value; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     total_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) * | ||||
|                   get_ticks_per_sec() / 1000000; | ||||
|  | ||||
|     if (env->cp15.c9_pmcr & PMCRD) { | ||||
|         /* Increment once every 64 processor clock cycles */ | ||||
|         total_ticks /= 64; | ||||
|     } | ||||
|     env->cp15.c15_ccnt = total_ticks - value; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||||
|                             uint64_t value) | ||||
| { | ||||
| @@ -604,10 +680,12 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { | ||||
|     { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, | ||||
|       .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, | ||||
|       .accessfn = pmreg_access }, | ||||
|     /* Unimplemented, RAZ/WI. */ | ||||
| #ifndef CONFIG_USER_ONLY | ||||
|     { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0, | ||||
|       .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, | ||||
|       .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO, | ||||
|       .readfn = pmccntr_read, .writefn = pmccntr_write, | ||||
|       .accessfn = pmreg_access }, | ||||
| #endif | ||||
|     { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, | ||||
|       .access = PL0_RW, | ||||
|       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper), | ||||
| @@ -1873,8 +1951,10 @@ void register_cp_regs_for_features(ARMCPU *cpu) | ||||
|     } | ||||
|     if (arm_feature(env, ARM_FEATURE_V7)) { | ||||
|         /* v7 performance monitor control register: same implementor | ||||
|          * field as main ID register, and we implement no event counters. | ||||
|          * field as main ID register, and we implement only the cycle | ||||
|          * count register. | ||||
|          */ | ||||
| #ifndef CONFIG_USER_ONLY | ||||
|         ARMCPRegInfo pmcr = { | ||||
|             .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, | ||||
|             .access = PL0_RW, .resetvalue = cpu->midr & 0xff000000, | ||||
| @@ -1882,12 +1962,13 @@ void register_cp_regs_for_features(ARMCPU *cpu) | ||||
|             .accessfn = pmreg_access, .writefn = pmcr_write, | ||||
|             .raw_writefn = raw_write, | ||||
|         }; | ||||
|         define_one_arm_cp_reg(cpu, &pmcr); | ||||
| #endif | ||||
|         ARMCPRegInfo clidr = { | ||||
|             .name = "CLIDR", .state = ARM_CP_STATE_BOTH, | ||||
|             .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1, | ||||
|             .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr | ||||
|         }; | ||||
|         define_one_arm_cp_reg(cpu, &pmcr); | ||||
|         define_one_arm_cp_reg(cpu, &clidr); | ||||
|         define_arm_cp_regs(cpu, v7_cp_reginfo); | ||||
|     } else { | ||||
| @@ -2478,7 +2559,7 @@ uint32_t cpsr_read(CPUARMState *env) | ||||
|         (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) | ||||
|         | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) | ||||
|         | ((env->condexec_bits & 0xfc) << 8) | ||||
|         | (env->GE << 16) | env->daif; | ||||
|         | (env->GE << 16) | (env->daif & CPSR_AIF); | ||||
| } | ||||
|  | ||||
| void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | ||||
|   | ||||
| @@ -50,6 +50,7 @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE, | ||||
|                    i32, i32, i32, i32) | ||||
| DEF_HELPER_2(exception, void, env, i32) | ||||
| DEF_HELPER_1(wfi, void, env) | ||||
| DEF_HELPER_1(wfe, void, env) | ||||
|  | ||||
| DEF_HELPER_3(cpsr_write, void, env, i32, i32) | ||||
| DEF_HELPER_1(cpsr_read, i32, env) | ||||
|   | ||||
| @@ -225,6 +225,15 @@ void HELPER(wfi)(CPUARMState *env) | ||||
|     cpu_loop_exit(env); | ||||
| } | ||||
|  | ||||
| void HELPER(wfe)(CPUARMState *env) | ||||
| { | ||||
|     /* Don't actually halt the CPU, just yield back to top | ||||
|      * level loop | ||||
|      */ | ||||
|     env->exception_index = EXCP_YIELD; | ||||
|     cpu_loop_exit(env); | ||||
| } | ||||
|  | ||||
| void HELPER(exception)(CPUARMState *env, uint32_t excp) | ||||
| { | ||||
|     env->exception_index = excp; | ||||
|   | ||||
| @@ -210,7 +210,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) | ||||
|     if (use_goto_tb(s, n, dest)) { | ||||
|         tcg_gen_goto_tb(n); | ||||
|         gen_a64_set_pc_im(dest); | ||||
|         tcg_gen_exit_tb((tcg_target_long)tb + n); | ||||
|         tcg_gen_exit_tb((intptr_t)tb + n); | ||||
|         s->is_jmp = DISAS_TB_JUMP; | ||||
|     } else { | ||||
|         gen_a64_set_pc_im(dest); | ||||
|   | ||||
| @@ -3939,6 +3939,9 @@ static void gen_nop_hint(DisasContext *s, int val) | ||||
|         s->is_jmp = DISAS_WFI; | ||||
|         break; | ||||
|     case 2: /* wfe */ | ||||
|         gen_set_pc_im(s, s->pc); | ||||
|         s->is_jmp = DISAS_WFE; | ||||
|         break; | ||||
|     case 4: /* sev */ | ||||
|     case 5: /* sevl */ | ||||
|         /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */ | ||||
| @@ -10857,6 +10860,9 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, | ||||
|         case DISAS_WFI: | ||||
|             gen_helper_wfi(cpu_env); | ||||
|             break; | ||||
|         case DISAS_WFE: | ||||
|             gen_helper_wfe(cpu_env); | ||||
|             break; | ||||
|         case DISAS_SWI: | ||||
|             gen_exception(EXCP_SWI); | ||||
|             break; | ||||
|   | ||||
| @@ -44,6 +44,8 @@ extern TCGv_ptr cpu_env; | ||||
|  * emitting unreachable code at the end of the TB in the A64 decoder | ||||
|  */ | ||||
| #define DISAS_EXC 6 | ||||
| /* WFE */ | ||||
| #define DISAS_WFE 7 | ||||
|  | ||||
| #ifdef TARGET_AARCH64 | ||||
| void a64_translate_init(void); | ||||
|   | ||||
| @@ -339,7 +339,7 @@ static const ExtSaveArea ext_save_areas[] = { | ||||
|     [3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, | ||||
|             .offset = 0x3c0, .size = 0x40  }, | ||||
|     [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, | ||||
|             .offset = 0x400, .size = 0x10  }, | ||||
|             .offset = 0x400, .size = 0x40  }, | ||||
| }; | ||||
|  | ||||
| const char *get_register_name_32(unsigned int reg) | ||||
|   | ||||
| @@ -13,6 +13,11 @@ | ||||
| #include "tcg-be-ldst.h" | ||||
| #include "qemu/bitops.h" | ||||
|  | ||||
| /* We're going to re-use TCGType in setting of the SF bit, which controls | ||||
|    the size of the operation performed.  If we know the values match, it | ||||
|    makes things much cleaner.  */ | ||||
| QEMU_BUILD_BUG_ON(TCG_TYPE_I32 != 0 || TCG_TYPE_I64 != 1); | ||||
|  | ||||
| #ifndef NDEBUG | ||||
| static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { | ||||
|     "%x0", "%x1", "%x2", "%x3", "%x4", "%x5", "%x6", "%x7", | ||||
| @@ -66,24 +71,22 @@ static const int tcg_target_call_oarg_regs[1] = { | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
| static inline void reloc_pc26(void *code_ptr, tcg_target_long target) | ||||
| static inline void reloc_pc26(void *code_ptr, intptr_t target) | ||||
| { | ||||
|     tcg_target_long offset; uint32_t insn; | ||||
|     offset = (target - (tcg_target_long)code_ptr) / 4; | ||||
|     intptr_t offset = (target - (intptr_t)code_ptr) / 4; | ||||
|     /* read instruction, mask away previous PC_REL26 parameter contents, | ||||
|        set the proper offset, then write back the instruction. */ | ||||
|     insn = *(uint32_t *)code_ptr; | ||||
|     uint32_t insn = *(uint32_t *)code_ptr; | ||||
|     insn = deposit32(insn, 0, 26, offset); | ||||
|     *(uint32_t *)code_ptr = insn; | ||||
| } | ||||
|  | ||||
| static inline void reloc_pc19(void *code_ptr, tcg_target_long target) | ||||
| static inline void reloc_pc19(void *code_ptr, intptr_t target) | ||||
| { | ||||
|     tcg_target_long offset; uint32_t insn; | ||||
|     offset = (target - (tcg_target_long)code_ptr) / 4; | ||||
|     intptr_t offset = (target - (intptr_t)code_ptr) / 4; | ||||
|     /* read instruction, mask away previous PC_REL19 parameter contents, | ||||
|        set the proper offset, then write back the instruction. */ | ||||
|     insn = *(uint32_t *)code_ptr; | ||||
|     uint32_t insn = *(uint32_t *)code_ptr; | ||||
|     insn = deposit32(insn, 5, 19, offset); | ||||
|     *(uint32_t *)code_ptr = insn; | ||||
| } | ||||
| @@ -302,18 +305,8 @@ static inline void tcg_out_ldst_9(TCGContext *s, | ||||
|                                   TCGReg rd, TCGReg rn, tcg_target_long offset) | ||||
| { | ||||
|     /* use LDUR with BASE register with 9bit signed unscaled offset */ | ||||
|     unsigned int mod, off; | ||||
|  | ||||
|     if (offset < 0) { | ||||
|         off = (256 + offset); | ||||
|         mod = 0x1; | ||||
|     } else { | ||||
|         off = offset; | ||||
|         mod = 0x0; | ||||
|     } | ||||
|  | ||||
|     mod |= op_type; | ||||
|     tcg_out32(s, op_data << 24 | mod << 20 | off << 12 | rn << 5 | rd); | ||||
|     tcg_out32(s, op_data << 24 | op_type << 20 | ||||
|               | (offset & 0x1ff) << 12 | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| /* tcg_out_ldst_12 expects a scaled unsigned immediate offset */ | ||||
| @@ -327,7 +320,8 @@ static inline void tcg_out_ldst_12(TCGContext *s, | ||||
|               | op_type << 20 | scaled_uimm << 10 | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_movr(TCGContext *s, int ext, TCGReg rd, TCGReg src) | ||||
| static inline void tcg_out_movr(TCGContext *s, TCGType ext, | ||||
|                                 TCGReg rd, TCGReg src) | ||||
| { | ||||
|     /* register to register move using MOV (shifted register with no shift) */ | ||||
|     /* using MOV 0x2a0003e0 | (shift).. */ | ||||
| @@ -408,7 +402,8 @@ static inline void tcg_out_ldst(TCGContext *s, enum aarch64_ldst_op_data data, | ||||
| } | ||||
|  | ||||
| /* mov alias implemented with add immediate, useful to move to/from SP */ | ||||
| static inline void tcg_out_movr_sp(TCGContext *s, int ext, TCGReg rd, TCGReg rn) | ||||
| static inline void tcg_out_movr_sp(TCGContext *s, TCGType ext, | ||||
|                                    TCGReg rd, TCGReg rn) | ||||
| { | ||||
|     /* using ADD 0x11000000 | (ext) | rn << 5 | rd */ | ||||
|     unsigned int base = ext ? 0x91000000 : 0x11000000; | ||||
| @@ -438,7 +433,7 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc, | ||||
|                                  int ext, TCGReg rd, TCGReg rn, TCGReg rm, | ||||
|                                  TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, | ||||
|                                  int shift_imm) | ||||
| { | ||||
|     /* Using shifted register arithmetic operations */ | ||||
| @@ -454,7 +449,7 @@ static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc, | ||||
|     tcg_out32(s, base | rm << 16 | shift | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_mul(TCGContext *s, int ext, | ||||
| static inline void tcg_out_mul(TCGContext *s, TCGType ext, | ||||
|                                TCGReg rd, TCGReg rn, TCGReg rm) | ||||
| { | ||||
|     /* Using MADD 0x1b000000 with Ra = wzr alias MUL 0x1b007c00 */ | ||||
| @@ -463,7 +458,7 @@ static inline void tcg_out_mul(TCGContext *s, int ext, | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_shiftrot_reg(TCGContext *s, | ||||
|                                         enum aarch64_srr_opc opc, int ext, | ||||
|                                         enum aarch64_srr_opc opc, TCGType ext, | ||||
|                                         TCGReg rd, TCGReg rn, TCGReg rm) | ||||
| { | ||||
|     /* using 2-source data processing instructions 0x1ac02000 */ | ||||
| @@ -471,23 +466,23 @@ static inline void tcg_out_shiftrot_reg(TCGContext *s, | ||||
|     tcg_out32(s, base | rm << 16 | opc << 8 | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_ubfm(TCGContext *s, int ext, TCGReg rd, TCGReg rn, | ||||
|                                 unsigned int a, unsigned int b) | ||||
| static inline void tcg_out_ubfm(TCGContext *s, TCGType ext, TCGReg rd, | ||||
|                                 TCGReg rn, unsigned int a, unsigned int b) | ||||
| { | ||||
|     /* Using UBFM 0x53000000 Wd, Wn, a, b */ | ||||
|     unsigned int base = ext ? 0xd3400000 : 0x53000000; | ||||
|     tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_sbfm(TCGContext *s, int ext, TCGReg rd, TCGReg rn, | ||||
|                                 unsigned int a, unsigned int b) | ||||
| static inline void tcg_out_sbfm(TCGContext *s, TCGType ext, TCGReg rd, | ||||
|                                 TCGReg rn, unsigned int a, unsigned int b) | ||||
| { | ||||
|     /* Using SBFM 0x13000000 Wd, Wn, a, b */ | ||||
|     unsigned int base = ext ? 0x93400000 : 0x13000000; | ||||
|     tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_extr(TCGContext *s, int ext, TCGReg rd, | ||||
| static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd, | ||||
|                                 TCGReg rn, TCGReg rm, unsigned int a) | ||||
| { | ||||
|     /* Using EXTR 0x13800000 Wd, Wn, Wm, a */ | ||||
| @@ -495,7 +490,7 @@ static inline void tcg_out_extr(TCGContext *s, int ext, TCGReg rd, | ||||
|     tcg_out32(s, base | rm << 16 | a << 10 | rn << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_shl(TCGContext *s, int ext, | ||||
| static inline void tcg_out_shl(TCGContext *s, TCGType ext, | ||||
|                                TCGReg rd, TCGReg rn, unsigned int m) | ||||
| { | ||||
|     int bits, max; | ||||
| @@ -504,28 +499,28 @@ static inline void tcg_out_shl(TCGContext *s, int ext, | ||||
|     tcg_out_ubfm(s, ext, rd, rn, bits - (m & max), max - (m & max)); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_shr(TCGContext *s, int ext, | ||||
| static inline void tcg_out_shr(TCGContext *s, TCGType ext, | ||||
|                                TCGReg rd, TCGReg rn, unsigned int m) | ||||
| { | ||||
|     int max = ext ? 63 : 31; | ||||
|     tcg_out_ubfm(s, ext, rd, rn, m & max, max); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_sar(TCGContext *s, int ext, | ||||
| static inline void tcg_out_sar(TCGContext *s, TCGType ext, | ||||
|                                TCGReg rd, TCGReg rn, unsigned int m) | ||||
| { | ||||
|     int max = ext ? 63 : 31; | ||||
|     tcg_out_sbfm(s, ext, rd, rn, m & max, max); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_rotr(TCGContext *s, int ext, | ||||
| static inline void tcg_out_rotr(TCGContext *s, TCGType ext, | ||||
|                                 TCGReg rd, TCGReg rn, unsigned int m) | ||||
| { | ||||
|     int max = ext ? 63 : 31; | ||||
|     tcg_out_extr(s, ext, rd, rn, rn, m & max); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_rotl(TCGContext *s, int ext, | ||||
| static inline void tcg_out_rotl(TCGContext *s, TCGType ext, | ||||
|                                 TCGReg rd, TCGReg rn, unsigned int m) | ||||
| { | ||||
|     int bits, max; | ||||
| @@ -534,24 +529,23 @@ static inline void tcg_out_rotl(TCGContext *s, int ext, | ||||
|     tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max)); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_cmp(TCGContext *s, int ext, TCGReg rn, TCGReg rm, | ||||
|                                int shift_imm) | ||||
| static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg rn, TCGReg rm) | ||||
| { | ||||
|     /* Using CMP alias SUBS wzr, Wn, Wm */ | ||||
|     tcg_out_arith(s, ARITH_SUBS, ext, TCG_REG_XZR, rn, rm, shift_imm); | ||||
|     tcg_out_arith(s, ARITH_SUBS, ext, TCG_REG_XZR, rn, rm, 0); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_cset(TCGContext *s, int ext, TCGReg rd, TCGCond c) | ||||
| static inline void tcg_out_cset(TCGContext *s, TCGType ext, | ||||
|                                 TCGReg rd, TCGCond c) | ||||
| { | ||||
|     /* Using CSET alias of CSINC 0x1a800400 Xd, XZR, XZR, invert(cond) */ | ||||
|     unsigned int base = ext ? 0x9a9f07e0 : 0x1a9f07e0; | ||||
|     tcg_out32(s, base | tcg_cond_to_aarch64[tcg_invert_cond(c)] << 12 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_goto(TCGContext *s, tcg_target_long target) | ||||
| static inline void tcg_out_goto(TCGContext *s, intptr_t target) | ||||
| { | ||||
|     tcg_target_long offset; | ||||
|     offset = (target - (tcg_target_long)s->code_ptr) / 4; | ||||
|     intptr_t offset = (target - (intptr_t)s->code_ptr) / 4; | ||||
|  | ||||
|     if (offset < -0x02000000 || offset >= 0x02000000) { | ||||
|         /* out of 26bit range */ | ||||
| @@ -582,11 +576,9 @@ static inline void tcg_out_goto_cond_noaddr(TCGContext *s, TCGCond c) | ||||
|     tcg_out32(s, insn); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c, | ||||
|                                      tcg_target_long target) | ||||
| static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c, intptr_t target) | ||||
| { | ||||
|     tcg_target_long offset; | ||||
|     offset = (target - (tcg_target_long)s->code_ptr) / 4; | ||||
|     intptr_t offset = (target - (intptr_t)s->code_ptr) / 4; | ||||
|  | ||||
|     if (offset < -0x40000 || offset >= 0x40000) { | ||||
|         /* out of 19bit range */ | ||||
| @@ -607,11 +599,9 @@ static inline void tcg_out_gotor(TCGContext *s, TCGReg reg) | ||||
|     tcg_out32(s, 0xd61f0000 | reg << 5); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_call(TCGContext *s, tcg_target_long target) | ||||
| static inline void tcg_out_call(TCGContext *s, intptr_t target) | ||||
| { | ||||
|     tcg_target_long offset; | ||||
|  | ||||
|     offset = (target - (tcg_target_long)s->code_ptr) / 4; | ||||
|     intptr_t offset = (target - (intptr_t)s->code_ptr) / 4; | ||||
|  | ||||
|     if (offset < -0x02000000 || offset >= 0x02000000) { /* out of 26bit rng */ | ||||
|         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, target); | ||||
| @@ -638,7 +628,7 @@ aarch64_limm(unsigned int m, unsigned int r) | ||||
|    to test a 32bit reg against 0xff000000, pass M = 8,  R = 8. | ||||
|    to test a 32bit reg against 0xff0000ff, pass M = 16, R = 8. | ||||
|  */ | ||||
| static inline void tcg_out_tst(TCGContext *s, int ext, TCGReg rn, | ||||
| static inline void tcg_out_tst(TCGContext *s, TCGType ext, TCGReg rn, | ||||
|                                unsigned int m, unsigned int r) | ||||
| { | ||||
|     /* using TST alias of ANDS XZR, Xn,#bimm64 0x7200001f */ | ||||
| @@ -647,8 +637,8 @@ static inline void tcg_out_tst(TCGContext *s, int ext, TCGReg rn, | ||||
| } | ||||
|  | ||||
| /* and a register with a bit pattern, similarly to TST, no flags change */ | ||||
| static inline void tcg_out_andi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, | ||||
|                                 unsigned int m, unsigned int r) | ||||
| static inline void tcg_out_andi(TCGContext *s, TCGType ext, TCGReg rd, | ||||
|                                 TCGReg rn, unsigned int m, unsigned int r) | ||||
| { | ||||
|     /* using AND 0x12000000 */ | ||||
|     unsigned int base = ext ? 0x92400000 : 0x12000000; | ||||
| @@ -663,9 +653,8 @@ static inline void tcg_out_ret(TCGContext *s) | ||||
|  | ||||
| void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) | ||||
| { | ||||
|     tcg_target_long target, offset; | ||||
|     target = (tcg_target_long)addr; | ||||
|     offset = (target - (tcg_target_long)jmp_addr) / 4; | ||||
|     intptr_t target = addr; | ||||
|     intptr_t offset = (target - (intptr_t)jmp_addr) / 4; | ||||
|  | ||||
|     if (offset < -0x02000000 || offset >= 0x02000000) { | ||||
|         /* out of 26bit range */ | ||||
| @@ -701,21 +690,23 @@ static inline void tcg_out_goto_label_cond(TCGContext *s, | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_rev(TCGContext *s, int ext, TCGReg rd, TCGReg rm) | ||||
| static inline void tcg_out_rev(TCGContext *s, TCGType ext, | ||||
|                                TCGReg rd, TCGReg rm) | ||||
| { | ||||
|     /* using REV 0x5ac00800 */ | ||||
|     unsigned int base = ext ? 0xdac00c00 : 0x5ac00800; | ||||
|     tcg_out32(s, base | rm << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_rev16(TCGContext *s, int ext, TCGReg rd, TCGReg rm) | ||||
| static inline void tcg_out_rev16(TCGContext *s, TCGType ext, | ||||
|                                  TCGReg rd, TCGReg rm) | ||||
| { | ||||
|     /* using REV16 0x5ac00400 */ | ||||
|     unsigned int base = ext ? 0xdac00400 : 0x5ac00400; | ||||
|     tcg_out32(s, base | rm << 5 | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_sxt(TCGContext *s, int ext, int s_bits, | ||||
| static inline void tcg_out_sxt(TCGContext *s, TCGType ext, int s_bits, | ||||
|                                TCGReg rd, TCGReg rn) | ||||
| { | ||||
|     /* using ALIASes SXTB 0x13001c00, SXTH 0x13003c00, SXTW 0x93407c00 | ||||
| @@ -733,7 +724,7 @@ static inline void tcg_out_uxt(TCGContext *s, int s_bits, | ||||
|     tcg_out_ubfm(s, 0, rd, rn, 0, bits); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_addi(TCGContext *s, int ext, | ||||
| static inline void tcg_out_addi(TCGContext *s, TCGType ext, | ||||
|                                 TCGReg rd, TCGReg rn, unsigned int aimm) | ||||
| { | ||||
|     /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */ | ||||
| @@ -753,7 +744,7 @@ static inline void tcg_out_addi(TCGContext *s, int ext, | ||||
|     tcg_out32(s, base | aimm | (rn << 5) | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_subi(TCGContext *s, int ext, | ||||
| static inline void tcg_out_subi(TCGContext *s, TCGType ext, | ||||
|                                 TCGReg rd, TCGReg rn, unsigned int aimm) | ||||
| { | ||||
|     /* sub immediate aimm unsigned 12bit value (with LSL 0 or 12) */ | ||||
| @@ -773,11 +764,6 @@ static inline void tcg_out_subi(TCGContext *s, int ext, | ||||
|     tcg_out32(s, base | aimm | (rn << 5) | rd); | ||||
| } | ||||
|  | ||||
| static inline void tcg_out_nop(TCGContext *s) | ||||
| { | ||||
|     tcg_out32(s, 0xd503201f); | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_SOFTMMU | ||||
| /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, | ||||
|  *                                     int mmu_idx, uintptr_t ra) | ||||
| @@ -801,7 +787,8 @@ static const void * const qemu_st_helpers[4] = { | ||||
|  | ||||
| static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) | ||||
| { | ||||
|     reloc_pc19(lb->label_ptr[0], (tcg_target_long)s->code_ptr); | ||||
|     reloc_pc19(lb->label_ptr[0], (intptr_t)s->code_ptr); | ||||
|  | ||||
|     tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0); | ||||
|     tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, lb->addrlo_reg); | ||||
|     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, lb->mem_index); | ||||
| @@ -815,23 +802,21 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) | ||||
|         tcg_out_movr(s, 1, lb->datalo_reg, TCG_REG_X0); | ||||
|     } | ||||
|  | ||||
|     tcg_out_goto(s, (tcg_target_long)lb->raddr); | ||||
|     tcg_out_goto(s, (intptr_t)lb->raddr); | ||||
| } | ||||
|  | ||||
| static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) | ||||
| { | ||||
|     reloc_pc19(lb->label_ptr[0], (tcg_target_long)s->code_ptr); | ||||
|     reloc_pc19(lb->label_ptr[0], (intptr_t)s->code_ptr); | ||||
|  | ||||
|     tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0); | ||||
|     tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, lb->addrlo_reg); | ||||
|     tcg_out_movr(s, 1, TCG_REG_X2, lb->datalo_reg); | ||||
|     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, lb->mem_index); | ||||
|     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_X4, (tcg_target_long)lb->raddr); | ||||
|     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_X4, (intptr_t)lb->raddr); | ||||
|     tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, | ||||
|                  (tcg_target_long)qemu_st_helpers[lb->opc & 3]); | ||||
|                  (intptr_t)qemu_st_helpers[lb->opc & 3]); | ||||
|     tcg_out_callr(s, TCG_REG_TMP); | ||||
|  | ||||
|     tcg_out_nop(s); | ||||
|     tcg_out_goto(s, (tcg_target_long)lb->raddr); | ||||
| } | ||||
|  | ||||
| @@ -893,7 +878,7 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, | ||||
|                  (is_read ? offsetof(CPUTLBEntry, addr_read) | ||||
|                   : offsetof(CPUTLBEntry, addr_write))); | ||||
|     /* Perform the address comparison. */ | ||||
|     tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3, 0); | ||||
|     tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3); | ||||
|     *label_ptr = s->code_ptr; | ||||
|     /* If not equal, we jump to the slow path. */ | ||||
|     tcg_out_goto_cond_noaddr(s, TCG_COND_NE); | ||||
| @@ -1088,16 +1073,23 @@ static inline void tcg_out_load_pair(TCGContext *s, TCGReg addr, | ||||
| } | ||||
|  | ||||
| static void tcg_out_op(TCGContext *s, TCGOpcode opc, | ||||
|                        const TCGArg *args, const int *const_args) | ||||
|                        const TCGArg args[TCG_MAX_OP_ARGS], | ||||
|                        const int const_args[TCG_MAX_OP_ARGS]) | ||||
| { | ||||
|     /* ext will be set in the switch below, which will fall through to the | ||||
|        common code. It triggers the use of extended regs where appropriate. */ | ||||
|     int ext = 0; | ||||
|     /* 99% of the time, we can signal the use of extension registers | ||||
|        by looking to see if the opcode handles 64-bit data.  */ | ||||
|     TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0; | ||||
|  | ||||
|     /* Hoist the loads of the most common arguments.  */ | ||||
|     TCGArg a0 = args[0]; | ||||
|     TCGArg a1 = args[1]; | ||||
|     TCGArg a2 = args[2]; | ||||
|     int c2 = const_args[2]; | ||||
|  | ||||
|     switch (opc) { | ||||
|     case INDEX_op_exit_tb: | ||||
|         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, args[0]); | ||||
|         tcg_out_goto(s, (tcg_target_long)tb_ret_addr); | ||||
|         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0); | ||||
|         tcg_out_goto(s, (intptr_t)tb_ret_addr); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_goto_tb: | ||||
| @@ -1105,23 +1097,23 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, | ||||
| #error "USE_DIRECT_JUMP required for aarch64" | ||||
| #endif | ||||
|         assert(s->tb_jmp_offset != NULL); /* consistency for USE_DIRECT_JUMP */ | ||||
|         s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; | ||||
|         s->tb_jmp_offset[a0] = s->code_ptr - s->code_buf; | ||||
|         /* actual branch destination will be patched by | ||||
|            aarch64_tb_set_jmp_target later, beware retranslation. */ | ||||
|         tcg_out_goto_noaddr(s); | ||||
|         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; | ||||
|         s->tb_next_offset[a0] = s->code_ptr - s->code_buf; | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_call: | ||||
|         if (const_args[0]) { | ||||
|             tcg_out_call(s, args[0]); | ||||
|             tcg_out_call(s, a0); | ||||
|         } else { | ||||
|             tcg_out_callr(s, args[0]); | ||||
|             tcg_out_callr(s, a0); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_br: | ||||
|         tcg_out_goto_label(s, args[0]); | ||||
|         tcg_out_goto_label(s, a0); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_ld_i32: | ||||
| @@ -1144,123 +1136,95 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, | ||||
|     case INDEX_op_st16_i64: | ||||
|     case INDEX_op_st32_i64: | ||||
|         tcg_out_ldst(s, aarch64_ldst_get_data(opc), aarch64_ldst_get_type(opc), | ||||
|                      args[0], args[1], args[2]); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_mov_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_mov_i32: | ||||
|         tcg_out_movr(s, ext, args[0], args[1]); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_movi_i64: | ||||
|         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]); | ||||
|         break; | ||||
|     case INDEX_op_movi_i32: | ||||
|         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]); | ||||
|                      a0, a1, a2); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_add_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_add_i32: | ||||
|         tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2], 0); | ||||
|         tcg_out_arith(s, ARITH_ADD, ext, a0, a1, a2, 0); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_sub_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_sub_i32: | ||||
|         tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2], 0); | ||||
|         tcg_out_arith(s, ARITH_SUB, ext, a0, a1, a2, 0); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_and_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_and_i32: | ||||
|         tcg_out_arith(s, ARITH_AND, ext, args[0], args[1], args[2], 0); | ||||
|         tcg_out_arith(s, ARITH_AND, ext, a0, a1, a2, 0); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_or_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_or_i32: | ||||
|         tcg_out_arith(s, ARITH_OR, ext, args[0], args[1], args[2], 0); | ||||
|         tcg_out_arith(s, ARITH_OR, ext, a0, a1, a2, 0); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_xor_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_xor_i32: | ||||
|         tcg_out_arith(s, ARITH_XOR, ext, args[0], args[1], args[2], 0); | ||||
|         tcg_out_arith(s, ARITH_XOR, ext, a0, a1, a2, 0); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_mul_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_mul_i32: | ||||
|         tcg_out_mul(s, ext, args[0], args[1], args[2]); | ||||
|         tcg_out_mul(s, ext, a0, a1, a2); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_shl_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_shl_i32: | ||||
|         if (const_args[2]) {    /* LSL / UBFM Wd, Wn, (32 - m) */ | ||||
|             tcg_out_shl(s, ext, args[0], args[1], args[2]); | ||||
|         if (c2) {    /* LSL / UBFM Wd, Wn, (32 - m) */ | ||||
|             tcg_out_shl(s, ext, a0, a1, a2); | ||||
|         } else {                /* LSL / LSLV */ | ||||
|             tcg_out_shiftrot_reg(s, SRR_SHL, ext, args[0], args[1], args[2]); | ||||
|             tcg_out_shiftrot_reg(s, SRR_SHL, ext, a0, a1, a2); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_shr_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_shr_i32: | ||||
|         if (const_args[2]) {    /* LSR / UBFM Wd, Wn, m, 31 */ | ||||
|             tcg_out_shr(s, ext, args[0], args[1], args[2]); | ||||
|         if (c2) {    /* LSR / UBFM Wd, Wn, m, 31 */ | ||||
|             tcg_out_shr(s, ext, a0, a1, a2); | ||||
|         } else {                /* LSR / LSRV */ | ||||
|             tcg_out_shiftrot_reg(s, SRR_SHR, ext, args[0], args[1], args[2]); | ||||
|             tcg_out_shiftrot_reg(s, SRR_SHR, ext, a0, a1, a2); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_sar_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_sar_i32: | ||||
|         if (const_args[2]) {    /* ASR / SBFM Wd, Wn, m, 31 */ | ||||
|             tcg_out_sar(s, ext, args[0], args[1], args[2]); | ||||
|         if (c2) {    /* ASR / SBFM Wd, Wn, m, 31 */ | ||||
|             tcg_out_sar(s, ext, a0, a1, a2); | ||||
|         } else {                /* ASR / ASRV */ | ||||
|             tcg_out_shiftrot_reg(s, SRR_SAR, ext, args[0], args[1], args[2]); | ||||
|             tcg_out_shiftrot_reg(s, SRR_SAR, ext, a0, a1, a2); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_rotr_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_rotr_i32: | ||||
|         if (const_args[2]) {    /* ROR / EXTR Wd, Wm, Wm, m */ | ||||
|             tcg_out_rotr(s, ext, args[0], args[1], args[2]); | ||||
|         if (c2) {    /* ROR / EXTR Wd, Wm, Wm, m */ | ||||
|             tcg_out_rotr(s, ext, a0, a1, a2); | ||||
|         } else {                /* ROR / RORV */ | ||||
|             tcg_out_shiftrot_reg(s, SRR_ROR, ext, args[0], args[1], args[2]); | ||||
|             tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, a2); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_rotl_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_rotl_i32:     /* same as rotate right by (32 - m) */ | ||||
|         if (const_args[2]) {    /* ROR / EXTR Wd, Wm, Wm, 32 - m */ | ||||
|             tcg_out_rotl(s, ext, args[0], args[1], args[2]); | ||||
|         if (c2) {    /* ROR / EXTR Wd, Wm, Wm, 32 - m */ | ||||
|             tcg_out_rotl(s, ext, a0, a1, a2); | ||||
|         } else { | ||||
|             tcg_out_arith(s, ARITH_SUB, 0, | ||||
|                           TCG_REG_TMP, TCG_REG_XZR, args[2], 0); | ||||
|             tcg_out_shiftrot_reg(s, SRR_ROR, ext, | ||||
|                                  args[0], args[1], TCG_REG_TMP); | ||||
|             tcg_out_arith(s, ARITH_SUB, 0, TCG_REG_TMP, TCG_REG_XZR, a2, 0); | ||||
|             tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, TCG_REG_TMP); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_brcond_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_brcond_i32: /* CMP 0, 1, cond(2), label 3 */ | ||||
|         tcg_out_cmp(s, ext, args[0], args[1], 0); | ||||
|         tcg_out_goto_label_cond(s, args[2], args[3]); | ||||
|     case INDEX_op_brcond_i32: | ||||
|         tcg_out_cmp(s, ext, a0, a1); | ||||
|         tcg_out_goto_label_cond(s, a2, args[3]); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_setcond_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_setcond_i32: | ||||
|         tcg_out_cmp(s, ext, args[1], args[2], 0); | ||||
|         tcg_out_cset(s, 0, args[0], args[3]); | ||||
|         tcg_out_cmp(s, ext, a1, a2); | ||||
|         tcg_out_cset(s, 0, a0, args[3]); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_qemu_ld8u: | ||||
| @@ -1300,44 +1264,50 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, | ||||
|         tcg_out_qemu_st(s, args, 3); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_bswap64_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_bswap32_i64: | ||||
|         /* Despite the _i64, this is a 32-bit bswap.  */ | ||||
|         ext = 0; | ||||
|         /* FALLTHRU */ | ||||
|     case INDEX_op_bswap64_i64: | ||||
|     case INDEX_op_bswap32_i32: | ||||
|         tcg_out_rev(s, ext, args[0], args[1]); | ||||
|         tcg_out_rev(s, ext, a0, a1); | ||||
|         break; | ||||
|     case INDEX_op_bswap16_i64: | ||||
|     case INDEX_op_bswap16_i32: | ||||
|         tcg_out_rev16(s, 0, args[0], args[1]); | ||||
|         tcg_out_rev16(s, 0, a0, a1); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_ext8s_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_ext8s_i32: | ||||
|         tcg_out_sxt(s, ext, 0, args[0], args[1]); | ||||
|         tcg_out_sxt(s, ext, 0, a0, a1); | ||||
|         break; | ||||
|     case INDEX_op_ext16s_i64: | ||||
|         ext = 1; /* fall through */ | ||||
|     case INDEX_op_ext16s_i32: | ||||
|         tcg_out_sxt(s, ext, 1, args[0], args[1]); | ||||
|         tcg_out_sxt(s, ext, 1, a0, a1); | ||||
|         break; | ||||
|     case INDEX_op_ext32s_i64: | ||||
|         tcg_out_sxt(s, 1, 2, args[0], args[1]); | ||||
|         tcg_out_sxt(s, 1, 2, a0, a1); | ||||
|         break; | ||||
|     case INDEX_op_ext8u_i64: | ||||
|     case INDEX_op_ext8u_i32: | ||||
|         tcg_out_uxt(s, 0, args[0], args[1]); | ||||
|         tcg_out_uxt(s, 0, a0, a1); | ||||
|         break; | ||||
|     case INDEX_op_ext16u_i64: | ||||
|     case INDEX_op_ext16u_i32: | ||||
|         tcg_out_uxt(s, 1, args[0], args[1]); | ||||
|         tcg_out_uxt(s, 1, a0, a1); | ||||
|         break; | ||||
|     case INDEX_op_ext32u_i64: | ||||
|         tcg_out_movr(s, 0, args[0], args[1]); | ||||
|         tcg_out_movr(s, 0, a0, a1); | ||||
|         break; | ||||
|  | ||||
|     case INDEX_op_mov_i64: | ||||
|     case INDEX_op_mov_i32: | ||||
|     case INDEX_op_movi_i64: | ||||
|     case INDEX_op_movi_i32: | ||||
|         /* Always implemented with tcg_out_mov/i, never with tcg_out_op.  */ | ||||
|     default: | ||||
|         tcg_abort(); /* opcode not implemented */ | ||||
|         /* Opcode not implemented.  */ | ||||
|         tcg_abort(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1441,12 +1411,6 @@ static const TCGTargetOpDef aarch64_op_defs[] = { | ||||
|  | ||||
| static void tcg_target_init(TCGContext *s) | ||||
| { | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
|     /* fail safe */ | ||||
|     if ((1ULL << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) { | ||||
|         tcg_abort(); | ||||
|     } | ||||
| #endif | ||||
|     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); | ||||
|     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); | ||||
|  | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -34,7 +34,7 @@ typedef struct { | ||||
|     gchar *asl;            /* asl code generated from aml */ | ||||
|     gsize asl_len; | ||||
|     gchar *asl_file; | ||||
|     bool asl_file_retain;   /* do not delete the temp asl */ | ||||
|     bool tmp_files_retain;   /* do not delete the temp asl/aml */ | ||||
| } QEMU_PACKED AcpiSdtTable; | ||||
|  | ||||
| typedef struct { | ||||
| @@ -153,7 +153,8 @@ static void free_test_data(test_data *data) | ||||
|             g_free(temp->aml); | ||||
|         } | ||||
|         if (temp->aml_file) { | ||||
|             if (g_strstr_len(temp->aml_file, -1, "aml-")) { | ||||
|             if (!temp->tmp_files_retain && | ||||
|                 g_strstr_len(temp->aml_file, -1, "aml-")) { | ||||
|                 unlink(temp->aml_file); | ||||
|             } | ||||
|             g_free(temp->aml_file); | ||||
| @@ -162,7 +163,7 @@ static void free_test_data(test_data *data) | ||||
|             g_free(temp->asl); | ||||
|         } | ||||
|         if (temp->asl_file) { | ||||
|             if (!temp->asl_file_retain) { | ||||
|             if (!temp->tmp_files_retain) { | ||||
|                 unlink(temp->asl_file); | ||||
|             } | ||||
|             g_free(temp->asl_file); | ||||
| @@ -410,7 +411,7 @@ static bool compare_signature(AcpiSdtTable *sdt, uint32_t signature) | ||||
|    return sdt->header.signature == signature; | ||||
| } | ||||
|  | ||||
| static void load_asl(GArray *sdts, AcpiSdtTable *sdt) | ||||
| static bool load_asl(GArray *sdts, AcpiSdtTable *sdt) | ||||
| { | ||||
|     AcpiSdtTable *temp; | ||||
|     GError *error = NULL; | ||||
| @@ -439,18 +440,22 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) | ||||
|     g_string_append_printf(command_line, "-d %s", sdt->aml_file); | ||||
|  | ||||
|     /* pass 'out' and 'out_err' in order to be redirected */ | ||||
|     g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error); | ||||
|     ret = g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error); | ||||
|     g_assert_no_error(error); | ||||
|  | ||||
|     ret = g_file_get_contents(sdt->asl_file, (gchar **)&sdt->asl, | ||||
|                               &sdt->asl_len, &error); | ||||
|     g_assert(ret); | ||||
|     g_assert_no_error(error); | ||||
|     g_assert(sdt->asl_len); | ||||
|     if (ret) { | ||||
|         ret = g_file_get_contents(sdt->asl_file, (gchar **)&sdt->asl, | ||||
|                                   &sdt->asl_len, &error); | ||||
|         g_assert(ret); | ||||
|         g_assert_no_error(error); | ||||
|         g_assert(sdt->asl_len); | ||||
|     } | ||||
|  | ||||
|     g_free(out); | ||||
|     g_free(out_err); | ||||
|     g_string_free(command_line, true); | ||||
|  | ||||
|     return !ret; | ||||
| } | ||||
|  | ||||
| #define COMMENT_END "*/" | ||||
| @@ -517,6 +522,7 @@ static void test_acpi_asl(test_data *data) | ||||
|     int i; | ||||
|     AcpiSdtTable *sdt, *exp_sdt; | ||||
|     test_data exp_data; | ||||
|     gboolean exp_err, err; | ||||
|  | ||||
|     memset(&exp_data, 0, sizeof(exp_data)); | ||||
|     exp_data.tables = load_expected_aml(data); | ||||
| @@ -527,20 +533,24 @@ static void test_acpi_asl(test_data *data) | ||||
|         sdt = &g_array_index(data->tables, AcpiSdtTable, i); | ||||
|         exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i); | ||||
|  | ||||
|         load_asl(data->tables, sdt); | ||||
|         err = load_asl(data->tables, sdt); | ||||
|         asl = normalize_asl(sdt->asl); | ||||
|  | ||||
|         load_asl(exp_data.tables, exp_sdt); | ||||
|         exp_err = load_asl(exp_data.tables, exp_sdt); | ||||
|         exp_asl = normalize_asl(exp_sdt->asl); | ||||
|  | ||||
|         /* TODO: check for warnings */ | ||||
|         g_assert(!err || exp_err); | ||||
|  | ||||
|         if (g_strcmp0(asl->str, exp_asl->str)) { | ||||
|             sdt->asl_file_retain = true; | ||||
|             exp_sdt->asl_file_retain = true; | ||||
|             sdt->tmp_files_retain = true; | ||||
|             exp_sdt->tmp_files_retain = true; | ||||
|             fprintf(stderr, | ||||
|                     "acpi-test: Warning! %.4s mismatch. " | ||||
|                     "Orig asl: %s, expected asl %s.\n", | ||||
|                     "Actual [asl:%s, aml:%s], Expected [asl:%s, aml:%s].\n", | ||||
|                     (gchar *)&exp_sdt->header.signature, | ||||
|                     sdt->asl_file, exp_sdt->asl_file); | ||||
|                     sdt->asl_file, sdt->aml_file, | ||||
|                     exp_sdt->asl_file, exp_sdt->aml_file); | ||||
|         } | ||||
|         g_string_free(asl, true); | ||||
|         g_string_free(exp_asl, true); | ||||
|   | ||||
| @@ -140,7 +140,7 @@ static void do_spawn_thread(ThreadPool *pool) | ||||
|     pool->new_threads--; | ||||
|     pool->pending_threads++; | ||||
|  | ||||
|     qemu_thread_create(&t, worker_thread, pool, QEMU_THREAD_DETACHED); | ||||
|     qemu_thread_create(&t, "worker", worker_thread, pool, QEMU_THREAD_DETACHED); | ||||
| } | ||||
|  | ||||
| static void spawn_thread_bh_fn(void *opaque) | ||||
|   | ||||
| @@ -486,6 +486,7 @@ runstate_set(int new_state) "new state %d" | ||||
| g_malloc(size_t size, void *ptr) "size %zu ptr %p" | ||||
| g_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p" | ||||
| g_free(void *ptr) "ptr %p" | ||||
| system_wakeup_request(int reason) "reason=%d" | ||||
|  | ||||
| # block/qcow2.c | ||||
| qcow2_writev_start_req(void *co, int64_t sector, int nb_sectors) "co %p sector %" PRIx64 " nb_sectors %d" | ||||
| @@ -1039,8 +1040,8 @@ vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x" | ||||
| vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp" | ||||
|  | ||||
| # savevm.c | ||||
| savevm_section_start(void) "" | ||||
| savevm_section_end(unsigned int section_id) "section_id %u" | ||||
| savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u" | ||||
| savevm_section_end(const char *id, unsigned int section_id) "%s, section_id %u" | ||||
|  | ||||
| # arch_init.c | ||||
| migration_bitmap_sync_start(void) "" | ||||
|   | ||||
| @@ -354,6 +354,7 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd, | ||||
|                                DisplaySurface *surface) | ||||
| { | ||||
|     SimpleSpiceUpdate *update; | ||||
|     bool need_destroy; | ||||
|  | ||||
|     dprint(1, "%s/%d:\n", __func__, ssd->qxl.id); | ||||
|  | ||||
| @@ -366,14 +367,19 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd, | ||||
|     } | ||||
|  | ||||
|     qemu_mutex_lock(&ssd->lock); | ||||
|     need_destroy = (ssd->ds != NULL); | ||||
|     ssd->ds = surface; | ||||
|     while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) { | ||||
|         QTAILQ_REMOVE(&ssd->updates, update, next); | ||||
|         qemu_spice_destroy_update(ssd, update); | ||||
|     } | ||||
|     qemu_mutex_unlock(&ssd->lock); | ||||
|     qemu_spice_destroy_host_primary(ssd); | ||||
|     qemu_spice_create_host_primary(ssd); | ||||
|     if (need_destroy) { | ||||
|         qemu_spice_destroy_host_primary(ssd); | ||||
|     } | ||||
|     if (ssd->ds) { | ||||
|         qemu_spice_create_host_primary(ssd); | ||||
|     } | ||||
|  | ||||
|     memset(&ssd->dirty, 0, sizeof(ssd->dirty)); | ||||
|     ssd->notify++; | ||||
| @@ -537,10 +543,29 @@ static void interface_set_client_capabilities(QXLInstance *sin, | ||||
| } | ||||
|  | ||||
| static int interface_client_monitors_config(QXLInstance *sin, | ||||
|                                         VDAgentMonitorsConfig *monitors_config) | ||||
|                                             VDAgentMonitorsConfig *mc) | ||||
| { | ||||
|     dprint(3, "%s:\n", __func__); | ||||
|     return 0; /* == not supported by guest */ | ||||
|     SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl); | ||||
|     QemuUIInfo info; | ||||
|     int rc; | ||||
|  | ||||
|     /* | ||||
|      * FIXME: multihead is tricky due to the way | ||||
|      * spice has multihead implemented. | ||||
|      */ | ||||
|     memset(&info, 0, sizeof(info)); | ||||
|     if (mc->num_of_monitors > 0) { | ||||
|         info.width  = mc->monitors[0].width; | ||||
|         info.height = mc->monitors[0].height; | ||||
|     } | ||||
|     rc = dpy_set_ui_info(ssd->dcl.con, &info); | ||||
|     dprint(1, "%s/%d: size %dx%d, rc %d   <---   ==========================\n", | ||||
|            __func__, ssd->qxl.id, info.width, info.height, rc); | ||||
|     if (rc != 0) { | ||||
|         return 0; /* == not supported by guest */ | ||||
|     } else { | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static const QXLInterface dpy_interface = { | ||||
| @@ -610,8 +635,6 @@ static void qemu_spice_display_init_one(QemuConsole *con) | ||||
|     ssd->dcl.ops = &display_listener_ops; | ||||
|     ssd->dcl.con = con; | ||||
|     register_displaychangelistener(&ssd->dcl); | ||||
|  | ||||
|     qemu_spice_create_host_primary(ssd); | ||||
| } | ||||
|  | ||||
| void qemu_spice_display_init(void) | ||||
|   | ||||
| @@ -330,7 +330,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) | ||||
|     } else { | ||||
|         errors = tight_detect_smooth_image16(vs, w, h); | ||||
|     } | ||||
|     if (quality != -1) { | ||||
|     if (quality != (uint8_t)-1) { | ||||
|         return (errors < tight_conf[quality].jpeg_threshold); | ||||
|     } | ||||
|     return (errors < tight_conf[compression].gradient_threshold); | ||||
|   | ||||
| @@ -252,6 +252,8 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) | ||||
|  | ||||
|         if (job->vs->csock == -1) { | ||||
|             vnc_unlock_display(job->vs->vd); | ||||
|             /* Copy persistent encoding data */ | ||||
|             vnc_async_encoding_end(job->vs, &vs); | ||||
|             goto disconnected; | ||||
|         } | ||||
|  | ||||
| @@ -278,6 +280,9 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) | ||||
|         vnc_async_encoding_end(job->vs, &vs); | ||||
|  | ||||
| 	qemu_bh_schedule(job->vs->bh); | ||||
|     }  else { | ||||
|         /* Copy persistent encoding data */ | ||||
|         vnc_async_encoding_end(job->vs, &vs); | ||||
|     } | ||||
|     vnc_unlock_output(job->vs); | ||||
|  | ||||
| @@ -333,7 +338,8 @@ void vnc_start_worker_thread(void) | ||||
|         return ; | ||||
|  | ||||
|     q = vnc_queue_init(); | ||||
|     qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED); | ||||
|     qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, | ||||
|                        QEMU_THREAD_DETACHED); | ||||
|     queue = q; /* Set global queue */ | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										227
									
								
								ui/vnc.c
									
									
									
									
									
								
							
							
						
						
									
										227
									
								
								ui/vnc.c
									
									
									
									
									
								
							| @@ -417,8 +417,7 @@ out_error: | ||||
|    3) resolutions > 1024 | ||||
| */ | ||||
|  | ||||
| static int vnc_update_client(VncState *vs, int has_dirty); | ||||
| static int vnc_update_client_sync(VncState *vs, int has_dirty); | ||||
| static int vnc_update_client(VncState *vs, int has_dirty, bool sync); | ||||
| static void vnc_disconnect_start(VncState *vs); | ||||
|  | ||||
| static void vnc_colordepth(VncState *vs); | ||||
| @@ -431,29 +430,25 @@ static int vnc_refresh_server_surface(VncDisplay *vd); | ||||
| static void vnc_dpy_update(DisplayChangeListener *dcl, | ||||
|                            int x, int y, int w, int h) | ||||
| { | ||||
|     int i; | ||||
|     VncDisplay *vd = container_of(dcl, VncDisplay, dcl); | ||||
|     struct VncSurface *s = &vd->guest; | ||||
|     int width = surface_width(vd->ds); | ||||
|     int height = surface_height(vd->ds); | ||||
|  | ||||
|     h += y; | ||||
|  | ||||
|     /* round x down to ensure the loop only spans one 16-pixel block per, | ||||
|        iteration.  otherwise, if (x % 16) != 0, the last iteration may span | ||||
|        two 16-pixel blocks but we only mark the first as dirty | ||||
|     */ | ||||
|     w += (x % 16); | ||||
|     x -= (x % 16); | ||||
|     /* this is needed this to ensure we updated all affected | ||||
|      * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */ | ||||
|     w += (x % VNC_DIRTY_PIXELS_PER_BIT); | ||||
|     x -= (x % VNC_DIRTY_PIXELS_PER_BIT); | ||||
|  | ||||
|     x = MIN(x, width); | ||||
|     y = MIN(y, height); | ||||
|     w = MIN(x + w, width) - x; | ||||
|     h = MIN(h, height); | ||||
|     h = MIN(y + h, height); | ||||
|  | ||||
|     for (; y < h; y++) | ||||
|         for (i = 0; i < w; i += 16) | ||||
|             set_bit((x + i) / 16, s->dirty[y]); | ||||
|     for (; y < h; y++) { | ||||
|         bitmap_set(s->dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT, | ||||
|                    DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, | ||||
| @@ -571,6 +566,15 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y) | ||||
|     ptr += x * VNC_SERVER_FB_BYTES; | ||||
|     return ptr; | ||||
| } | ||||
| /* this sets only the visible pixels of a dirty bitmap */ | ||||
| #define VNC_SET_VISIBLE_PIXELS_DIRTY(bitmap, w, h) {\ | ||||
|         int y;\ | ||||
|         memset(bitmap, 0x00, sizeof(bitmap));\ | ||||
|         for (y = 0; y < h; y++) {\ | ||||
|             bitmap_set(bitmap[y], 0,\ | ||||
|                        DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));\ | ||||
|         } \ | ||||
|     } | ||||
|  | ||||
| static void vnc_dpy_switch(DisplayChangeListener *dcl, | ||||
|                            DisplaySurface *surface) | ||||
| @@ -596,7 +600,9 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl, | ||||
|     qemu_pixman_image_unref(vd->guest.fb); | ||||
|     vd->guest.fb = pixman_image_ref(surface->image); | ||||
|     vd->guest.format = surface->format; | ||||
|     memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty)); | ||||
|     VNC_SET_VISIBLE_PIXELS_DIRTY(vd->guest.dirty, | ||||
|                                  surface_width(vd->ds), | ||||
|                                  surface_height(vd->ds)); | ||||
|  | ||||
|     QTAILQ_FOREACH(vs, &vd->clients, next) { | ||||
|         vnc_colordepth(vs); | ||||
| @@ -604,7 +610,9 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl, | ||||
|         if (vs->vd->cursor) { | ||||
|             vnc_cursor_define(vs); | ||||
|         } | ||||
|         memset(vs->dirty, 0xFF, sizeof(vs->dirty)); | ||||
|         VNC_SET_VISIBLE_PIXELS_DIRTY(vs->dirty, | ||||
|                                      surface_width(vd->ds), | ||||
|                                      surface_height(vd->ds)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -751,7 +759,7 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl, | ||||
|     QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) { | ||||
|         if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { | ||||
|             vs->force_update = 1; | ||||
|             vnc_update_client_sync(vs, 1); | ||||
|             vnc_update_client(vs, 1, true); | ||||
|             /* vs might be free()ed here */ | ||||
|         } | ||||
|     } | ||||
| @@ -770,11 +778,12 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl, | ||||
|         y = dst_y + h - 1; | ||||
|         inc = -1; | ||||
|     } | ||||
|     w_lim = w - (16 - (dst_x % 16)); | ||||
|     if (w_lim < 0) | ||||
|     w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT)); | ||||
|     if (w_lim < 0) { | ||||
|         w_lim = w; | ||||
|     else | ||||
|         w_lim = w - (w_lim % 16); | ||||
|     } else { | ||||
|         w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT); | ||||
|     } | ||||
|     for (i = 0; i < h; i++) { | ||||
|         for (x = 0; x <= w_lim; | ||||
|                 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) { | ||||
| @@ -782,10 +791,11 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl, | ||||
|                 if ((s = w - w_lim) == 0) | ||||
|                     break; | ||||
|             } else if (!x) { | ||||
|                 s = (16 - (dst_x % 16)); | ||||
|                 s = (VNC_DIRTY_PIXELS_PER_BIT - | ||||
|                     (dst_x % VNC_DIRTY_PIXELS_PER_BIT)); | ||||
|                 s = MIN(s, w_lim); | ||||
|             } else { | ||||
|                 s = 16; | ||||
|                 s = VNC_DIRTY_PIXELS_PER_BIT; | ||||
|             } | ||||
|             cmp_bytes = s * VNC_SERVER_FB_BYTES; | ||||
|             if (memcmp(src_row, dst_row, cmp_bytes) == 0) | ||||
| @@ -793,7 +803,8 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl, | ||||
|             memmove(dst_row, src_row, cmp_bytes); | ||||
|             QTAILQ_FOREACH(vs, &vd->clients, next) { | ||||
|                 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { | ||||
|                     set_bit(((x + dst_x) / 16), vs->dirty[y]); | ||||
|                     set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT), | ||||
|                             vs->dirty[y]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -862,35 +873,24 @@ static int find_and_clear_dirty_height(struct VncState *vs, | ||||
|     int h; | ||||
|  | ||||
|     for (h = 1; h < (height - y); h++) { | ||||
|         int tmp_x; | ||||
|         if (!test_bit(last_x, vs->dirty[y + h])) { | ||||
|             break; | ||||
|         } | ||||
|         for (tmp_x = last_x; tmp_x < x; tmp_x++) { | ||||
|             clear_bit(tmp_x, vs->dirty[y + h]); | ||||
|         } | ||||
|         bitmap_clear(vs->dirty[y + h], last_x, x - last_x); | ||||
|     } | ||||
|  | ||||
|     return h; | ||||
| } | ||||
|  | ||||
| static int vnc_update_client_sync(VncState *vs, int has_dirty) | ||||
| { | ||||
|     int ret = vnc_update_client(vs, has_dirty); | ||||
|     vnc_jobs_join(vs); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static int vnc_update_client(VncState *vs, int has_dirty) | ||||
| static int vnc_update_client(VncState *vs, int has_dirty, bool sync) | ||||
| { | ||||
|     if (vs->need_update && vs->csock != -1) { | ||||
|         VncDisplay *vd = vs->vd; | ||||
|         VncJob *job; | ||||
|         int y; | ||||
|         int width, height; | ||||
|         int height; | ||||
|         int n = 0; | ||||
|  | ||||
|  | ||||
|         if (vs->output.offset && !vs->audio_cap && !vs->force_update) | ||||
|             /* kernel send buffers are full -> drop frames to throttle */ | ||||
|             return 0; | ||||
| @@ -906,33 +906,27 @@ static int vnc_update_client(VncState *vs, int has_dirty) | ||||
|          */ | ||||
|         job = vnc_job_new(vs); | ||||
|  | ||||
|         width = MIN(pixman_image_get_width(vd->server), vs->client_width); | ||||
|         height = MIN(pixman_image_get_height(vd->server), vs->client_height); | ||||
|  | ||||
|         for (y = 0; y < height; y++) { | ||||
|             int x; | ||||
|             int last_x = -1; | ||||
|             for (x = 0; x < width / 16; x++) { | ||||
|                 if (test_and_clear_bit(x, vs->dirty[y])) { | ||||
|                     if (last_x == -1) { | ||||
|                         last_x = x; | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (last_x != -1) { | ||||
|                         int h = find_and_clear_dirty_height(vs, y, last_x, x, | ||||
|                                                             height); | ||||
|  | ||||
|                         n += vnc_job_add_rect(job, last_x * 16, y, | ||||
|                                               (x - last_x) * 16, h); | ||||
|                     } | ||||
|                     last_x = -1; | ||||
|                 } | ||||
|             } | ||||
|             if (last_x != -1) { | ||||
|                 int h = find_and_clear_dirty_height(vs, y, last_x, x, height); | ||||
|                 n += vnc_job_add_rect(job, last_x * 16, y, | ||||
|                                       (x - last_x) * 16, h); | ||||
|         y = 0; | ||||
|         for (;;) { | ||||
|             int x, h; | ||||
|             unsigned long x2; | ||||
|             unsigned long offset = find_next_bit((unsigned long *) &vs->dirty, | ||||
|                                                  height * VNC_DIRTY_BPL(vs), | ||||
|                                                  y * VNC_DIRTY_BPL(vs)); | ||||
|             if (offset == height * VNC_DIRTY_BPL(vs)) { | ||||
|                 /* no more dirty bits */ | ||||
|                 break; | ||||
|             } | ||||
|             y = offset / VNC_DIRTY_BPL(vs); | ||||
|             x = offset % VNC_DIRTY_BPL(vs); | ||||
|             x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y], | ||||
|                                     VNC_DIRTY_BPL(vs), x); | ||||
|             bitmap_clear(vs->dirty[y], x, x2 - x); | ||||
|             h = find_and_clear_dirty_height(vs, y, x, x2, height); | ||||
|             n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y, | ||||
|                                   (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h); | ||||
|         } | ||||
|  | ||||
|         vnc_job_push(job); | ||||
| @@ -940,8 +934,11 @@ static int vnc_update_client(VncState *vs, int has_dirty) | ||||
|         return n; | ||||
|     } | ||||
|  | ||||
|     if (vs->csock == -1) | ||||
|     if (vs->csock == -1) { | ||||
|         vnc_disconnect_finish(vs); | ||||
|     } else if (sync) { | ||||
|         vnc_jobs_join(vs); | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
| @@ -1846,7 +1843,7 @@ static void framebuffer_update_request(VncState *vs, int incremental, | ||||
|                                        int w, int h) | ||||
| { | ||||
|     int i; | ||||
|     const size_t width = surface_width(vs->vd->ds) / 16; | ||||
|     const size_t width = surface_width(vs->vd->ds) / VNC_DIRTY_PIXELS_PER_BIT; | ||||
|     const size_t height = surface_height(vs->vd->ds); | ||||
|  | ||||
|     if (y_position > height) { | ||||
| @@ -2548,7 +2545,9 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) | ||||
|  | ||||
|         vs->lossy_rect[sty][stx] = 0; | ||||
|         for (j = 0; j < VNC_STAT_RECT; ++j) { | ||||
|             bitmap_set(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16); | ||||
|             bitmap_set(vs->dirty[y + j], | ||||
|                        x / VNC_DIRTY_PIXELS_PER_BIT, | ||||
|                        VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT); | ||||
|         } | ||||
|         has_dirty++; | ||||
|     } | ||||
| @@ -2652,8 +2651,8 @@ static int vnc_refresh_server_surface(VncDisplay *vd) | ||||
|     int width = pixman_image_get_width(vd->guest.fb); | ||||
|     int height = pixman_image_get_height(vd->guest.fb); | ||||
|     int y; | ||||
|     uint8_t *guest_row; | ||||
|     uint8_t *server_row; | ||||
|     uint8_t *guest_row0 = NULL, *server_row0; | ||||
|     int guest_stride = 0, server_stride; | ||||
|     int cmp_bytes; | ||||
|     VncState *vs; | ||||
|     int has_dirty = 0; | ||||
| @@ -2671,47 +2670,64 @@ static int vnc_refresh_server_surface(VncDisplay *vd) | ||||
|      * Check and copy modified bits from guest to server surface. | ||||
|      * Update server dirty map. | ||||
|      */ | ||||
|     cmp_bytes = 64; | ||||
|     cmp_bytes = VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES; | ||||
|     if (cmp_bytes > vnc_server_fb_stride(vd)) { | ||||
|         cmp_bytes = vnc_server_fb_stride(vd); | ||||
|     } | ||||
|     if (vd->guest.format != VNC_SERVER_FB_FORMAT) { | ||||
|         int width = pixman_image_get_width(vd->server); | ||||
|         tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width); | ||||
|     } else { | ||||
|         guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb); | ||||
|         guest_stride = pixman_image_get_stride(vd->guest.fb); | ||||
|     } | ||||
|     guest_row = (uint8_t *)pixman_image_get_data(vd->guest.fb); | ||||
|     server_row = (uint8_t *)pixman_image_get_data(vd->server); | ||||
|     for (y = 0; y < height; y++) { | ||||
|         if (!bitmap_empty(vd->guest.dirty[y], VNC_DIRTY_BITS)) { | ||||
|             int x; | ||||
|             uint8_t *guest_ptr; | ||||
|             uint8_t *server_ptr; | ||||
|     server_row0 = (uint8_t *)pixman_image_get_data(vd->server); | ||||
|     server_stride = pixman_image_get_stride(vd->server); | ||||
|  | ||||
|             if (vd->guest.format != VNC_SERVER_FB_FORMAT) { | ||||
|                 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y); | ||||
|                 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf); | ||||
|             } else { | ||||
|                 guest_ptr = guest_row; | ||||
|             } | ||||
|             server_ptr = server_row; | ||||
|  | ||||
|             for (x = 0; x + 15 < width; | ||||
|                     x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) { | ||||
|                 if (!test_and_clear_bit((x / 16), vd->guest.dirty[y])) | ||||
|                     continue; | ||||
|                 if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) | ||||
|                     continue; | ||||
|                 memcpy(server_ptr, guest_ptr, cmp_bytes); | ||||
|                 if (!vd->non_adaptive) | ||||
|                     vnc_rect_updated(vd, x, y, &tv); | ||||
|                 QTAILQ_FOREACH(vs, &vd->clients, next) { | ||||
|                     set_bit((x / 16), vs->dirty[y]); | ||||
|                 } | ||||
|                 has_dirty++; | ||||
|             } | ||||
|     y = 0; | ||||
|     for (;;) { | ||||
|         int x; | ||||
|         uint8_t *guest_ptr, *server_ptr; | ||||
|         unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty, | ||||
|                                              height * VNC_DIRTY_BPL(&vd->guest), | ||||
|                                              y * VNC_DIRTY_BPL(&vd->guest)); | ||||
|         if (offset == height * VNC_DIRTY_BPL(&vd->guest)) { | ||||
|             /* no more dirty bits */ | ||||
|             break; | ||||
|         } | ||||
|         guest_row  += pixman_image_get_stride(vd->guest.fb); | ||||
|         server_row += pixman_image_get_stride(vd->server); | ||||
|         y = offset / VNC_DIRTY_BPL(&vd->guest); | ||||
|         x = offset % VNC_DIRTY_BPL(&vd->guest); | ||||
|  | ||||
|         server_ptr = server_row0 + y * server_stride + x * cmp_bytes; | ||||
|  | ||||
|         if (vd->guest.format != VNC_SERVER_FB_FORMAT) { | ||||
|             qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y); | ||||
|             guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf); | ||||
|         } else { | ||||
|             guest_ptr = guest_row0 + y * guest_stride; | ||||
|         } | ||||
|         guest_ptr += x * cmp_bytes; | ||||
|  | ||||
|         for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT); | ||||
|              x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) { | ||||
|             if (!test_and_clear_bit(x, vd->guest.dirty[y])) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) { | ||||
|                 continue; | ||||
|             } | ||||
|             memcpy(server_ptr, guest_ptr, cmp_bytes); | ||||
|             if (!vd->non_adaptive) { | ||||
|                 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT, | ||||
|                                  y, &tv); | ||||
|             } | ||||
|             QTAILQ_FOREACH(vs, &vd->clients, next) { | ||||
|                 set_bit(x, vs->dirty[y]); | ||||
|             } | ||||
|             has_dirty++; | ||||
|         } | ||||
|  | ||||
|         y++; | ||||
|     } | ||||
|     qemu_pixman_image_unref(tmpbuf); | ||||
|     return has_dirty; | ||||
| @@ -2734,7 +2750,7 @@ static void vnc_refresh(DisplayChangeListener *dcl) | ||||
|     vnc_unlock_display(vd); | ||||
|  | ||||
|     QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) { | ||||
|         rects += vnc_update_client(vs, has_dirty); | ||||
|         rects += vnc_update_client(vs, has_dirty, false); | ||||
|         /* vs might be free()ed here */ | ||||
|     } | ||||
|  | ||||
| @@ -3134,7 +3150,9 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp) | ||||
|             acl = 1; | ||||
| #endif | ||||
|         } else if (strncmp(options, "lossy", 5) == 0) { | ||||
| #ifdef CONFIG_VNC_JPEG | ||||
|             vs->lossy = true; | ||||
| #endif | ||||
|         } else if (strncmp(options, "non-adaptive", 12) == 0) { | ||||
|             vs->non_adaptive = true; | ||||
|         } else if (strncmp(options, "share=", 6) == 0) { | ||||
| @@ -3151,6 +3169,13 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* adaptive updates are only used with tight encoding and | ||||
|      * if lossy updates are enabled so we can disable all the | ||||
|      * calculations otherwise */ | ||||
|     if (!vs->lossy) { | ||||
|         vs->non_adaptive = true; | ||||
|     } | ||||
|  | ||||
| #ifdef CONFIG_VNC_TLS | ||||
|     if (acl && x509 && vs->tls.x509verify) { | ||||
|         if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) { | ||||
|   | ||||
							
								
								
									
										10
									
								
								ui/vnc.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ui/vnc.h
									
									
									
									
									
								
							| @@ -81,8 +81,16 @@ typedef void VncSendHextileTile(VncState *vs, | ||||
| #define VNC_MAX_WIDTH 2560 | ||||
| #define VNC_MAX_HEIGHT 2048 | ||||
|  | ||||
| /* VNC_DIRTY_PIXELS_PER_BIT is the number of dirty pixels represented | ||||
|  * by one bit in the dirty bitmap */ | ||||
| #define VNC_DIRTY_PIXELS_PER_BIT 16 | ||||
|  | ||||
| /* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */ | ||||
| #define VNC_DIRTY_BITS (VNC_MAX_WIDTH / 16) | ||||
| #define VNC_DIRTY_BITS (VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT) | ||||
|  | ||||
| /* VNC_DIRTY_BPL (BPL = bits per line) might be greater than | ||||
|  * VNC_DIRTY_BITS due to alignment */ | ||||
| #define VNC_DIRTY_BPL(x) (sizeof((x)->dirty) / VNC_MAX_HEIGHT * BITS_PER_BYTE) | ||||
|  | ||||
| #define VNC_STAT_RECT  64 | ||||
| #define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT) | ||||
|   | ||||
| @@ -88,7 +88,8 @@ static int qemu_signalfd_compat(const sigset_t *mask) | ||||
|     memcpy(&info->mask, mask, sizeof(*mask)); | ||||
|     info->fd = fds[1]; | ||||
|  | ||||
|     qemu_thread_create(&thread, sigwait_compat, info, QEMU_THREAD_DETACHED); | ||||
|     qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info, | ||||
|                        QEMU_THREAD_DETACHED); | ||||
|  | ||||
|     return fds[0]; | ||||
| } | ||||
|   | ||||
| @@ -27,6 +27,13 @@ | ||||
| #include "qemu/thread.h" | ||||
| #include "qemu/atomic.h" | ||||
|  | ||||
| static bool name_threads; | ||||
|  | ||||
| void qemu_thread_naming(bool enable) | ||||
| { | ||||
|     name_threads = enable; | ||||
| } | ||||
|  | ||||
| static void error_exit(int err, const char *msg) | ||||
| { | ||||
|     fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); | ||||
| @@ -387,8 +394,7 @@ void qemu_event_wait(QemuEvent *ev) | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void qemu_thread_create(QemuThread *thread, | ||||
| void qemu_thread_create(QemuThread *thread, const char *name, | ||||
|                        void *(*start_routine)(void*), | ||||
|                        void *arg, int mode) | ||||
| { | ||||
| @@ -414,6 +420,12 @@ void qemu_thread_create(QemuThread *thread, | ||||
|     if (err) | ||||
|         error_exit(err, __func__); | ||||
|  | ||||
| #if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 12)) | ||||
|     if (name_threads) { | ||||
|         pthread_setname_np(thread->thread, name); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     pthread_sigmask(SIG_SETMASK, &oldset, NULL); | ||||
|  | ||||
|     pthread_attr_destroy(&attr); | ||||
|   | ||||
| @@ -16,6 +16,14 @@ | ||||
| #include <assert.h> | ||||
| #include <limits.h> | ||||
|  | ||||
| static bool name_threads; | ||||
|  | ||||
| void qemu_thread_naming(bool enable) | ||||
| { | ||||
|     /* But note we don't actually name them on Windows yet */ | ||||
|     name_threads = enable; | ||||
| } | ||||
|  | ||||
| static void error_exit(int err, const char *msg) | ||||
| { | ||||
|     char *pstr; | ||||
| @@ -325,7 +333,7 @@ void *qemu_thread_join(QemuThread *thread) | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| void qemu_thread_create(QemuThread *thread, | ||||
| void qemu_thread_create(QemuThread *thread, const char *name, | ||||
|                        void *(*start_routine)(void *), | ||||
|                        void *arg, int mode) | ||||
| { | ||||
|   | ||||
							
								
								
									
										63
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								vl.c
									
									
									
									
									
								
							| @@ -479,6 +479,33 @@ static QemuOptsList qemu_msg_opts = { | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| static QemuOptsList qemu_name_opts = { | ||||
|     .name = "name", | ||||
|     .implied_opt_name = "guest", | ||||
|     .merge_lists = true, | ||||
|     .head = QTAILQ_HEAD_INITIALIZER(qemu_name_opts.head), | ||||
|     .desc = { | ||||
|         { | ||||
|             .name = "guest", | ||||
|             .type = QEMU_OPT_STRING, | ||||
|             .help = "Sets the name of the guest.\n" | ||||
|                     "This name will be displayed in the SDL window caption.\n" | ||||
|                     "The name will also be used for the VNC server", | ||||
|         }, { | ||||
|             .name = "process", | ||||
|             .type = QEMU_OPT_STRING, | ||||
|             .help = "Sets the name of the QEMU process, as shown in top etc", | ||||
|         }, { | ||||
|             .name = "debug-threads", | ||||
|             .type = QEMU_OPT_BOOL, | ||||
|             .help = "When enabled, name the individual threads; defaults off.\n" | ||||
|                     "NOTE: The thread names are for debugging and not a\n" | ||||
|                     "stable API.", | ||||
|         }, | ||||
|         { /* End of list */ } | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Get machine options | ||||
|  * | ||||
| @@ -929,6 +956,21 @@ static int parse_sandbox(QemuOpts *opts, void *opaque) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static void parse_name(QemuOpts *opts) | ||||
| { | ||||
|     const char *proc_name; | ||||
|  | ||||
|     if (qemu_opt_get(opts, "debug-threads")) { | ||||
|         qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false)); | ||||
|     } | ||||
|     qemu_name = qemu_opt_get(opts, "guest"); | ||||
|  | ||||
|     proc_name = qemu_opt_get(opts, "process"); | ||||
|     if (proc_name) { | ||||
|         os_set_proc_name(proc_name); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool usb_enabled(bool default_usb) | ||||
| { | ||||
|     return qemu_opt_get_bool(qemu_get_machine_opts(), "usb", default_usb); | ||||
| @@ -1837,6 +1879,8 @@ void qemu_register_suspend_notifier(Notifier *notifier) | ||||
|  | ||||
| void qemu_system_wakeup_request(WakeupReason reason) | ||||
| { | ||||
|     trace_system_wakeup_request(reason); | ||||
|  | ||||
|     if (!runstate_check(RUN_STATE_SUSPENDED)) { | ||||
|         return; | ||||
|     } | ||||
| @@ -2887,6 +2931,7 @@ int main(int argc, char **argv, char **envp) | ||||
|     qemu_add_opts(&qemu_tpmdev_opts); | ||||
|     qemu_add_opts(&qemu_realtime_opts); | ||||
|     qemu_add_opts(&qemu_msg_opts); | ||||
|     qemu_add_opts(&qemu_name_opts); | ||||
|  | ||||
|     runstate_init(); | ||||
|  | ||||
| @@ -3632,19 +3677,11 @@ int main(int argc, char **argv, char **envp) | ||||
|                                 "is no longer supported.\n"); | ||||
|                 break; | ||||
|             case QEMU_OPTION_name: | ||||
|                 qemu_name = g_strdup(optarg); | ||||
| 		 { | ||||
| 		     char *p = strchr(qemu_name, ','); | ||||
| 		     if (p != NULL) { | ||||
| 		        *p++ = 0; | ||||
| 			if (strncmp(p, "process=", 8)) { | ||||
| 			    fprintf(stderr, "Unknown subargument %s to -name\n", p); | ||||
| 			    exit(1); | ||||
| 			} | ||||
| 			p += 8; | ||||
| 			os_set_proc_name(p); | ||||
| 		     } | ||||
| 		 } | ||||
|                 opts = qemu_opts_parse(qemu_find_opts("name"), optarg, 1); | ||||
|                 if (!opts) { | ||||
|                     exit(1); | ||||
|                 } | ||||
|                 parse_name(opts); | ||||
|                 break; | ||||
|             case QEMU_OPTION_prom_env: | ||||
|                 if (nb_prom_envs >= MAX_PROM_ENVS) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user